﻿using HalconDotNet;
using Kimd.Common;
using Kimd.Communication;
using Kimd.Logic;
using Kimd.Machine;
using Kimd.Motion;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using WorkStation.Common;
using WorkStation.UI.Controls;
using static log4net.Appender.RollingFileAppender;

namespace WorkStation.Logic
{
    //名称: Robot1模组 ,  Robot2模组
    public class RobotLogic : FlowBase
    {
        //0 前面的手臂  1 后面的手臂
        private int _moduleIndex;
        private CommunicationHelper _robot;
        private CommunicationHelper _vision;
        private PLCOperator _plc;
        private Tray _robotFeedTray;
        private Tray _robotRecycleTray;
        private Tray _robotTotalTray;
        private Tray _feedHalfTray1;
        private Tray _feedHalfTray2;
        private Tray _recycleHalfTray1;
        private Tray _recycleHalfTray2;
        private RobotStatus _status;
        //private List<Cylinder> _upVacs;
        //private List<Cylinder> _downVacs;
        private Sensor _upInOrigin;
        private Sensor _upInMove;
        private List<Sensor> _feedVacSenses;
        public Action<string> SwitchProductAct;
        //private Cylinder _upPositionCylinder1;
        //private Cylinder _upPositionCylinder2;
        //private Cylinder _downPositionCylinder1;
        //private Cylinder _downPositionCylinder2;


        private List<Cylinder> _upFeedPositionCylinder;
        private List<Cylinder> _downFeedPositionCylinder;
        private List<Cylinder> _upRecyclePositionCylinder;
        private List<Cylinder> _downRecyclePositionCylinder;
        public RobotLogic(string flowName, FlowManager flowmanager, int moduleIndex)
            : base(flowName, flowmanager)
        {
            _moduleIndex = moduleIndex;
            _robot = new CommunicationHelper($"机械手{_moduleIndex + 1}", MachineResource.Instance.MachineTcpClient[$"机械手{_moduleIndex + 1}"]);
            if (_moduleIndex == 0)
                _vision = (flowmanager.SelectFlow("轨道拍照1") as CaptureTrayLogic).GetVision();
            else
                _vision = (flowmanager.SelectFlow("轨道拍照2") as CaptureTrayLogic).GetVision();
            this._plc = MachineResource.Instance.MachinePLC["轨道PLC"];
            if (_moduleIndex == 0)
            {
                //_upVacs = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位1上层真空吸1"],
                //    MachineResource.Instance.MachineCylinder["精定位1上层真空吸2"],
                //    MachineResource.Instance.MachineCylinder["精定位1上层真空吸3"],
                //    MachineResource.Instance.MachineCylinder["精定位1上层真空吸4"],
                //    MachineResource.Instance.MachineCylinder["精定位1上层真空吸5"],
                //    MachineResource.Instance.MachineCylinder["精定位1上层真空吸6"],
                //    MachineResource.Instance.MachineCylinder["精定位1上层真空吸7"],
                //    MachineResource.Instance.MachineCylinder["精定位1上层真空吸8"],
                //};
                //_downVacs = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位1下层真空吸1"],
                //    MachineResource.Instance.MachineCylinder["精定位1下层真空吸2"],
                //    MachineResource.Instance.MachineCylinder["精定位1下层真空吸3"],
                //    MachineResource.Instance.MachineCylinder["精定位1下层真空吸4"],
                //    MachineResource.Instance.MachineCylinder["精定位1下层真空吸5"],
                //    MachineResource.Instance.MachineCylinder["精定位1下层真空吸6"],
                //    MachineResource.Instance.MachineCylinder["精定位1下层真空吸7"],
                //    MachineResource.Instance.MachineCylinder["精定位1下层真空吸8"],
                //};
                this._upInOrigin = MachineResource.Instance.MachineSensor["精定位1上层移载气缸原点"];
                this._upInMove = MachineResource.Instance.MachineSensor["精定位1上层移载气缸动点"];

                this._feedVacSenses = new List<Sensor>()
                {
                    MachineResource.Instance.MachineSensor["机器人1真空达到1"],
                    MachineResource.Instance.MachineSensor["机器人1真空达到2"],
                    MachineResource.Instance.MachineSensor["机器人1真空达到3"],
                    MachineResource.Instance.MachineSensor["机器人1真空达到4"],
                    MachineResource.Instance.MachineSensor["机器人1真空达到5"],
                    MachineResource.Instance.MachineSensor["机器人1真空达到6"],
                    MachineResource.Instance.MachineSensor["机器人1真空达到7"],
                    MachineResource.Instance.MachineSensor["机器人1真空达到8"],
                };
                _upFeedPositionCylinder = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位1上层定位气缸2-2"],
                    MachineResource.Instance.MachineCylinder["精定位1上层定位气缸1-2"]
                };

                _downFeedPositionCylinder = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位1下层定位气缸2-2"],
                    MachineResource.Instance.MachineCylinder["精定位1下层定位气缸1-2"]
                };

                _upRecyclePositionCylinder = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位1上层定位气缸2"],
                    MachineResource.Instance.MachineCylinder["精定位1上层定位气缸1"]
                };

                _downRecyclePositionCylinder = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位1下层定位气缸2"],
                    MachineResource.Instance.MachineCylinder["精定位1下层定位气缸1"]
                };
            }
            else
            {
                //_upVacs = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位2上层真空吸1"],
                //    MachineResource.Instance.MachineCylinder["精定位2上层真空吸2"],
                //    MachineResource.Instance.MachineCylinder["精定位2上层真空吸3"],
                //    MachineResource.Instance.MachineCylinder["精定位2上层真空吸4"],
                //    MachineResource.Instance.MachineCylinder["精定位2上层真空吸5"],
                //    MachineResource.Instance.MachineCylinder["精定位2上层真空吸6"],
                //    MachineResource.Instance.MachineCylinder["精定位2上层真空吸7"],
                //    MachineResource.Instance.MachineCylinder["精定位2上层真空吸8"],
                //};
                //_downVacs = new List<Cylinder>()
                //{
                //    MachineResource.Instance.MachineCylinder["精定位2下层真空吸1"],
                //    MachineResource.Instance.MachineCylinder["精定位2下层真空吸2"],
                //    MachineResource.Instance.MachineCylinder["精定位2下层真空吸3"],
                //    MachineResource.Instance.MachineCylinder["精定位2下层真空吸4"],
                //    MachineResource.Instance.MachineCylinder["精定位2下层真空吸5"],
                //    MachineResource.Instance.MachineCylinder["精定位2下层真空吸6"],
                //    MachineResource.Instance.MachineCylinder["精定位2下层真空吸7"],
                //    MachineResource.Instance.MachineCylinder["精定位2下层真空吸8"],
                //};
                //this._upInOrigin = MachineResource.Instance.MachineSensor["精定位2上层移载气缸原点"];
                this._upInMove = MachineResource.Instance.MachineSensor["精定位2上层移载气缸动点"];

                this._feedVacSenses = new List<Sensor>()
                {
                    MachineResource.Instance.MachineSensor["机器人2真空达到1"],
                    MachineResource.Instance.MachineSensor["机器人2真空达到2"],
                    MachineResource.Instance.MachineSensor["机器人2真空达到3"],
                    MachineResource.Instance.MachineSensor["机器人2真空达到4"],
                    MachineResource.Instance.MachineSensor["机器人2真空达到5"],
                    MachineResource.Instance.MachineSensor["机器人2真空达到6"],
                    MachineResource.Instance.MachineSensor["机器人2真空达到7"],
                    MachineResource.Instance.MachineSensor["机器人2真空达到8"],
                };
                _upFeedPositionCylinder = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位2上层定位气缸1-2"],
                    MachineResource.Instance.MachineCylinder["精定位2上层定位气缸2-2"]
                };

                _downFeedPositionCylinder = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位2下层定位气缸1-2"],
                    MachineResource.Instance.MachineCylinder["精定位2下层定位气缸2-2"]
                };

                _upRecyclePositionCylinder = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位2上层定位气缸1"],
                    MachineResource.Instance.MachineCylinder["精定位2上层定位气缸2"]
                };

                _downRecyclePositionCylinder = new List<Cylinder>()
                {
                    MachineResource.Instance.MachineCylinder["精定位2下层定位气缸1"],
                    MachineResource.Instance.MachineCylinder["精定位2下层定位气缸2"]
                };
            }
            //机械手吸嘴
            // 5  1
            // 6  2
            _robotFeedTray = new Tray(2, 2);
            // 5 6对应feedTray1的1 2,   1 2对应feedTray2的1 2
            _robotFeedTray.Direction = TrayDir.YZ;
            // 7  3
            // 8  4
            _robotRecycleTray = new Tray(2, 2);
            // 7 8对应recycleTray1的1 2,   3 4对应recycleTray2的1 2
            _robotRecycleTray.Direction = TrayDir.YZ;

            _robotTotalTray = new Tray(2, 4);
            _robotTotalTray.Direction = TrayDir.XZ;

            _feedHalfTray1 = new Tray(2, 15);
            _feedHalfTray2 = new Tray(2, 15);
            _recycleHalfTray1 = new Tray(1, 15);
            _recycleHalfTray2 = new Tray(1, 15);

            RegisterDirectSignal("回零完成");
            RegisterDirectSignal("放料完成");
            RegisterDirectSignal("料取完");

            _robot.NotifyMessageReceived += _robot_NotifyMessageReceived;

            if (_moduleIndex == 0)
            {
                RegisterDirectSignal("机械手1回零完成");
                RegisterDirectSignal("机械手1标定完成");
            }

            #region 机械手气缸报警
            Task.Run(() =>
            {
                bool isWarnFlag = false;
                while (true)
                {
                    if (_moduleIndex == 0)
                    {
                        if (GlobalVariable.RobotCylinderWarn[_moduleIndex] && !isWarnFlag)
                        {
                            Thread.Sleep(100);
                            isWarnFlag = true;
                            GlobalVariable.AlreadyRobotCylinderWarn[_moduleIndex] = true;
                            ShowWarnAndPause($"机械手{moduleIndex + 1}气缸报警，{GlobalVariable.RobotCylinderWarnContent[moduleIndex]}", this.Description);
                            GlobalVariable.RobotCylinderWarnContent[moduleIndex] = string.Empty;
                        }
                        else if (!GlobalVariable.RobotCylinderWarn[_moduleIndex])
                        {
                            isWarnFlag = false;
                            GlobalVariable.AlreadyRobotCylinderWarn[_moduleIndex] = false;
                        }
                    }
                    else
                    {
                        if (GlobalVariable.RobotCylinderWarn[_moduleIndex] && !isWarnFlag)
                        {
                            isWarnFlag = true;
                            GlobalVariable.AlreadyRobotCylinderWarn[_moduleIndex] = true;
                            ShowWarnAndPause($"机械手{moduleIndex + 1}气缸报警，{GlobalVariable.RobotCylinderWarnContent[moduleIndex]}", this.Description);
                        }
                        else if (!GlobalVariable.RobotCylinderWarn[_moduleIndex])
                        {
                            isWarnFlag = false;
                            GlobalVariable.AlreadyRobotCylinderWarn[_moduleIndex] = false;
                        }
                    }
                    Thread.Sleep(2);
                }
            });
            #endregion
        }

        bool isAllPointsGot = false;
        bool receivedStart = false;
        string pointStr;


        bool startRecvJDW = false;
        bool SecondJDWOKRecv = false;
        bool SecondJDWResult = false;
        string JDWDetailCylinder = string.Empty;

        bool startRecvJDWPut = false;
        bool SecondJDWOKRecvPut = false;
        bool SecondJDWResultPut = false;
        string JDWPutDetailCylinder = string.Empty;


        bool startRecvJDWGet = false;
        bool SecondJDWOKRecvGet = false;
        bool SecondJDWResultGet = false;
        string JDWGetDetailCylinder = string.Empty;
        double Speed = 0;
        double Acc = 0;
        double Dec = 0;
        private void _robot_NotifyMessageReceived(ReceivePackage obj)
        {
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"{obj.Message}", this.Description, 0, "系统"));
            if (obj.Message.Contains("start"))
            {
                pointStr += obj.Message;
                receivedStart = true;
                if (obj.Message.Contains("end"))
                {
                    receivedStart = false;
                    isAllPointsGot = true;
                }
            }
            else if (obj.Message.Contains("end"))
            {
                pointStr += obj.Message;
                receivedStart = false;
                isAllPointsGot = true;
            }
            else if (receivedStart)
            {
                pointStr += obj.Message;
            }
            else if (startRecvJDWGet && obj.Message.Contains("JDW,Get"))
            {
                startRecvJDWGet = false;
                if (obj.Message.Contains("NG"))
                {
                    SecondJDWResultGet = false;
                    string str = obj.Message;
                    string[] strs = str.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                    if (strs.Length >= 3 + 8)
                    {
                        JDWGetDetailCylinder = string.Empty;
                        for (int i = 3; i < strs.Length; i++)
                        {
                            if (strs[i] == "1")
                            {
                                JDWGetDetailCylinder += $",爪{i - 2}";
                            }
                        }
                    }
                }
                else
                    SecondJDWResultGet = true;
                SecondJDWOKRecvGet = true;
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, "收到包含精定位Get的信息", this.Description, 0, "系统"));
            }
            else if (startRecvJDWPut && obj.Message.Contains("JDW,Put"))
            {
                startRecvJDWPut = false;
                if (obj.Message.Contains("NG"))
                {
                    SecondJDWResultPut = false;
                    string str = obj.Message;
                    string[] strs = str.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                    if (strs.Length >= 3 + 8)
                    {
                        JDWPutDetailCylinder = string.Empty;
                        for (int i = 3; i < strs.Length; i++)
                        {
                            if (strs[i] == "1")
                            {
                                JDWPutDetailCylinder += $",爪{i - 2}";
                            }
                        }
                    }
                }
                else
                    SecondJDWResultPut = true;
                SecondJDWOKRecvPut = true;
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, "收到包含精定位Put的信息", this.Description, 0, "系统"));
            }
            else if (startRecvJDW && obj.Message.Contains("JDW"))
            {
                startRecvJDW = false;
                if (obj.Message.Contains("NG"))
                {
                    SecondJDWResult = false;
                    string str = obj.Message;
                    string[] strs = str.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                    if (strs.Length >= 2 + 8)
                    {
                        JDWDetailCylinder = string.Empty;
                        for (int i = 2; i < strs.Length; i++)
                        {
                            if (strs[i] == "1")
                            {
                                JDWDetailCylinder += $",爪{i - 1}";
                            }
                        }
                    }
                }
                else
                    SecondJDWResult = true;
                SecondJDWOKRecv = true;
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, "收到包含精定位的信息", this.Description, 0, "系统"));
            }
            else if (obj.Message.Contains("CyWarn"))
            {
                string str = obj.Message;
                if (str.Contains(":"))
                {
                    string[] strs = str.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries);
                    if (strs.Count() >= 2)
                    {
                        GlobalVariable.RobotCylinderWarnContent[_moduleIndex] = strs[1];
                    }
                }

                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, "收到包含气缸报警的信息", this.Description, 0, "系统"));
            }
            else if (obj.Message.Contains("RobotCT"))
            {
                string str = obj.Message;
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"[RobotCT]:{str}", this.Description, 0, "系统"));
            }
            //else if (obj.Message.Contains("SwitchProduct"))
            //{
            //    SwitchProductAct?.Invoke(obj.Message);
            //}
        }
        public override void Calibrate()
        {
            //标定采用相对坐标
            //起始点是 0，0  偏移距离是 3mm  先移动x方向，正向移动
            if (!CheckFlowCondition()) return;
            if (_moduleIndex == 0)
            {
                if (MessageBox.Show("是否开始机械手1相机的九点标定?", "九点标定", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    double startX = 0;
                    double startY = 0;
                    double offsetX = 3;
                    double offsetY = -3;
                    for (int i = 0; i < 9; i++)
                    {
                        RobotCommandRun($"CaliNine,{i + 1}", "机械手至九点标定位置失败!", out string recvStr);
                        if (!CheckFlowCondition()) return;
                        retry:
                        SendPackage sp = new SendPackage();
                        sp.Message = $"Cali,Nine,{i + 1},{startX + (i % 3) * offsetX},{startY + i / 3 * offsetY},0";
                        sp.PairRule = null;
                        TcpClientSendAndReceive(_vision, sp, 5000, 3, out string result333);
                        if (result333.Contains("NG"))
                        {
                            ShowWarnAndPause("视觉拍九点标定点失败!", "Robot1模组");
                            if (!CheckFlowCondition()) return;
                            goto retry;
                        }
                    }
                }
                if (MessageBox.Show("是否开始机械手1上料Tray的标定?", "上料Tray标定", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    //机器人去取料
                    isAllPointsGot = false;
                    RobotCommandRun($"CaptureFeed,1", "机械手去上料拍照点位1失败!", out string recvStr11);
                    if (!CheckFlowCondition()) return;

                    //if (!GlobalVariable.IsDryRun)
                    {
                        while (!isAllPointsGot && !IsBreak())
                        {
                            Thread.Sleep(20);
                        }
                        isAllPointsGot = false;
                        ExtractPointsFromString3(pointStr);
                        pointStr = "";
                    }

                retry33:
                    SendPackage sp33 = new SendPackage();
                    sp33.Message = $"CaptureFeed,CaliMark,1,{capturePositionFeed1.X},{capturePositionFeed1.Y}";
                    sp33.PairRule = null;
                    TcpClientSendAndReceive(_vision, sp33, 5000, 3, out string result3333);
                    if (result3333.Contains("NG"))
                    {
                        ShowWarnAndPause("first point fail!", "Robot1模组");
                        if (!CheckFlowCondition()) return;
                        goto retry33;
                    }

                    isAllPointsGot = false;
                    RobotCommandRun($"CaptureFeed,2", "机械手去上料拍照点位2失败!", out string recvStr22);
                    if (!CheckFlowCondition()) return;

                    while (!isAllPointsGot && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    isAllPointsGot = false;
                    ExtractPointsFromString4(pointStr);
                    pointStr = "";

                retry22:
                    SendPackage s22p = new SendPackage();
                    s22p.Message = $"CaptureFeed,CaliMark,2,{capturePositionFeed2.X},{capturePositionFeed2.Y}";
                    s22p.PairRule = null;
                    TcpClientSendAndReceive(_vision, s22p, 5000, 3, out string resul22t);
                    if (resul22t.Contains("NG"))
                    {
                        ShowWarnAndPause("second point fail!", "Robot1模组");
                        if (!CheckFlowCondition()) return;
                        goto retry22;
                    }
                }
                if (MessageBox.Show("是否开始机械手1下料Tray的标定?", "下料Tray标定", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    isAllPointsGot = false;
                    RobotCommandRun($"CaptureTray,1", "机械手去下料拍照点位1失败!", out string recvStr1);
                    while (!isAllPointsGot && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    isAllPointsGot = false;
                    ExtractPointsFromString2(pointStr);
                    pointStr = "";

                retry3:
                    SendPackage sp3 = new SendPackage();
                    sp3.Message = $"CaptureBoat,CaliMark,1,{capturePosition1.X},{capturePosition1.Y}";
                    sp3.PairRule = null;
                    TcpClientSendAndReceive(_vision, sp3, 5000, 3, out string result);
                    if (result.Contains("NG"))
                    {
                        ShowWarnAndPause("first point fail!", "Robot1模组");
                        if (!CheckFlowCondition()) return;
                        goto retry3;
                    }

                    RobotCommandRun($"CaptureTray,2", "机械手去下料拍照点位2失败!", out string recvStr2);
                    if (!CheckFlowCondition()) return;

                    while (!isAllPointsGot && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    isAllPointsGot = false;
                    ExtractPointsFromString(pointStr);
                    pointStr = "";

                retry2:
                    SendPackage s2p = new SendPackage();
                    s2p.Message = $"CaptureBoat,CaliMark,2,{capturePosition2.X},{capturePosition2.Y}";
                    s2p.PairRule = null;
                    TcpClientSendAndReceive(_vision, s2p, 5000, 3, out string resul2t);
                    if (result.Contains("NG"))
                    {
                        ShowWarnAndPause("second point fail!", "Robot1模组");
                        if (!CheckFlowCondition()) return;
                        goto retry2;
                    }
                }
                ShowWarnAndPause("机械手1标定完成!", "Robot1模组", true);
                SetSignal("机械手1标定完成");
            }
            else
            {
                WaitForSignal("Robot1模组", "机械手1标定完成");
                if (!CheckFlowCondition()) return;
                if (MessageBox.Show("是否开始机械手2相机的九点标定?", "九点标定", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    double startX = 0;
                    double startY = 0;
                    double offsetX = 3;
                    double offsetY = -3;
                    for (int i = 0; i < 9; i++)
                    {
                        RobotCommandRun($"CaliNine,{i + 1}", "机械手至九点标定位置失败!", out string recvStr);
                        if (!CheckFlowCondition()) return;
                        retry:
                        SendPackage sp = new SendPackage();
                        sp.Message = $"Cali,Nine,{i + 1},{startX + (i % 3) * offsetX},{startY + i / 3 * offsetY},0";
                        sp.PairRule = null;
                        TcpClientSendAndReceive(_vision, sp, 5000, 3, out string result333);
                        if (result333.Contains("NG"))
                        {
                            ShowWarnAndPause("视觉拍九点标定点失败!", "Robot2模组");
                            if (!CheckFlowCondition()) return;
                            goto retry;
                        }
                    }
                }
                if (MessageBox.Show("是否开始机械手2上料Tray的标定?", "上料Tray标定", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    //机器人去取料
                    isAllPointsGot = false;
                    RobotCommandRun($"CaptureFeed,1", "机械手去上料拍照点位2失败!", out string recvStr11);
                    if (!CheckFlowCondition()) return;

                    //if (!GlobalVariable.IsDryRun)
                    {
                        while (!isAllPointsGot && !IsBreak())
                        {
                            Thread.Sleep(20);
                        }
                        isAllPointsGot = false;
                        ExtractPointsFromString3(pointStr);
                        pointStr = "";
                    }

                retry33:
                    SendPackage sp33 = new SendPackage();
                    sp33.Message = $"CaptureFeed,CaliMark,1,{capturePositionFeed1.X},{capturePositionFeed1.Y}";
                    sp33.PairRule = null;
                    TcpClientSendAndReceive(_vision, sp33, 5000, 3, out string result3333);
                    if (result3333.Contains("NG"))
                    {
                        ShowWarnAndPause("first point fail!", "Robot2模组");
                        if (!CheckFlowCondition()) return;
                        goto retry33;
                    }

                    isAllPointsGot = false;
                    RobotCommandRun($"CaptureFeed,2", "机械手去上料拍照点位2失败!", out string recvStr22);
                    if (!CheckFlowCondition()) return;

                    while (!isAllPointsGot && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    isAllPointsGot = false;
                    ExtractPointsFromString4(pointStr);
                    pointStr = "";

                retry22:
                    SendPackage s22p = new SendPackage();
                    s22p.Message = $"CaptureFeed,CaliMark,2,{capturePositionFeed2.X},{capturePositionFeed2.Y}";
                    s22p.PairRule = null;
                    TcpClientSendAndReceive(_vision, s22p, 5000, 3, out string resul22t);
                    if (resul22t.Contains("NG"))
                    {
                        ShowWarnAndPause("second point fail!", "Robot2模组");
                        if (!CheckFlowCondition()) return;
                        goto retry22;
                    }
                }
                if (MessageBox.Show("是否开始机械手2下料Tray的标定?", "下料Tray标定", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    isAllPointsGot = false;
                    RobotCommandRun($"CaptureTray,1", "机械手去下料拍照点位1失败!", out string recvStr1);
                    while (!isAllPointsGot && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    isAllPointsGot = false;
                    ExtractPointsFromString2(pointStr);
                    pointStr = "";

                retry3:
                    SendPackage sp3 = new SendPackage();
                    sp3.Message = $"CaptureBoat,CaliMark,1,{capturePosition1.X},{capturePosition1.Y}";
                    sp3.PairRule = null;
                    TcpClientSendAndReceive(_vision, sp3, 5000, 3, out string result);
                    if (result.Contains("NG"))
                    {
                        ShowWarnAndPause("first point fail!", "Robot2模组");
                        if (!CheckFlowCondition()) return;
                        goto retry3;
                    }

                    RobotCommandRun($"CaptureTray,2", "机械手去下料拍照点位2失败!", out string recvStr2);
                    if (!CheckFlowCondition()) return;

                    while (!isAllPointsGot && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    isAllPointsGot = false;
                    ExtractPointsFromString(pointStr);
                    pointStr = "";

                retry2:
                    SendPackage s2p = new SendPackage();
                    s2p.Message = $"CaptureBoat,CaliMark,2,{capturePosition2.X},{capturePosition2.Y}";
                    s2p.PairRule = null;
                    _vision.EmptySendBuffer();
                    TcpClientSendAndReceive(_vision, s2p, 5000, 3, out string resul2t);
                    if (result.Contains("NG"))
                    {
                        ShowWarnAndPause("second point fail!", "Robot2模组");
                        if (!CheckFlowCondition()) return;
                        goto retry2;
                    }
                }
                ShowWarnAndPause("机械手2标定完成!", "Robot2模组", true);
            }
        }
        public override void InSingleRunMode()
        {
            if (GlobalVariable.OnSingleRunPause != null)
                GlobalVariable.OnSingleRunPause();
        }
        public override void Home()
        {
            GlobalVariable.HasNotifyRobotSwitch = true;
            if (_moduleIndex == 0)
            {
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"{this.Description} 开始回零...", this.Description, 0, $"机械手{_moduleIndex + 1}"));
            rehome:
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拉低信号  机器人程序启动，机器人停止", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                GlobalVariable.RobotControlStatus[(int)RobotoutEnumRobot1.机器人程序启动] = false;
                GlobalVariable.RobotControlStatus[(int)RobotoutEnumRobot1.机器人停止] = false;
                Thread.Sleep(200);
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拉高信号  机器人停止", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                GlobalVariable.RobotControlStatus[(int)RobotoutEnumRobot1.机器人停止] = true;
                Thread.Sleep(200);
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拉高信号  机器人报警复位", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                GlobalVariable.RobotControlStatus[(int)RobotoutEnumRobot1.机器人报警复位] = true;

                Thread.Sleep(500);
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拉低信号  机器人报警复位", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                GlobalVariable.RobotControlStatus[(int)RobotoutEnumRobot1.机器人报警复位] = false;
                Thread.Sleep(500);

                if (!CheckFlowCondition()) return;
                //每次复位需要关闭TCP重新打开
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"关闭TCP", this.Description, 0, $"机械手{_moduleIndex + 1}"));

                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拉高信号  机器人程序复位", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                GlobalVariable.RobotControlStatus[(int)RobotoutEnumRobot1.机器人程序复位] = true;
                Thread.Sleep(500);
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拉低信号  机器人程序复位", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                GlobalVariable.RobotControlStatus[(int)RobotoutEnumRobot1.机器人程序复位] = false;
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拉高信号  机器人程序启动", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                GlobalVariable.RobotControlStatus[(int)RobotoutEnumRobot1.机器人程序启动] = true;
                Thread.Sleep(200);
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拉低信号  机器人程序启动", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                GlobalVariable.RobotControlStatus[(int)RobotoutEnumRobot1.机器人程序启动] = false;
                if (!CheckFlowCondition()) return;

                Thread.Sleep(2000);
                //等回零信号从OFF-->>ON 代表回零完成
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等回零信号从OFF-->>ON 代表回零完成", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                var watch = Stopwatch.StartNew();
                if (!isSimulate)
                {
                    while (!GlobalVariable.RobotStatus[(int)RobotinEnumRobot1.机器人回零完成] && !IsBreak())
                    {
                        Thread.Sleep(50);
                    }
                    if (!CheckFlowCondition()) return;
                    if (watch.ElapsedMilliseconds > 30000)
                    {
                        watch.Stop();
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Warn, $"机械手回零超时!", this.Description, 10, $"机械手{_moduleIndex + 1}"));
                        //出错，停下所有线程
                        _flowManager.Pause();
                        //若为报错，需重新检测启动信号
                        WaitForStart();
                        if (!CheckFlowCondition()) return;
                        goto rehome;
                    }
                    watch.Stop();
                }

                if (!CheckFlowCondition()) return;

                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"{this.Description} 回零完成!", this.Description, 0, $"机械手{_moduleIndex + 1}"));

                GlobalVariable.AlreadyOpenPrecisionFeedProductVacUp[0] = false;
                GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[0] = false;
                GlobalVariable.AlreadyOpenPrecisionFeedProductVacDown[0] = false;
                GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[0] = false;
                GlobalVariable.AlreadyOpenPrecisionFeedProductVacUp[1] = false;
                GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[1] = false;
                GlobalVariable.AlreadyOpenPrecisionFeedProductVacDown[1] = false;
                GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[1] = false;
                checkProductStatus();

                if (!CheckFlowCondition()) return;
                NotifyRobotSwitchProduct(_moduleIndex + 1);
                if (!CheckFlowCondition()) return;
                if (!GlobalVariable.HasNotifyRobotSwitch)
                {
                    ShowWarnAndPause("机械手1产品切换失败！", this.Description);
                }
                if (!CheckFlowCondition()) return;

                SetSignal("机械手1回零完成");
            }
            else
            {
                if (!SystemConfig.Instance.UsingStatus.IsRobot1Disable)
                    WaitForSignal("Robot1模组", "机械手1回零完成");
                if (!CheckFlowCondition()) return;
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"{this.Description} 开始回零...", this.Description, 0, $"机械手{_moduleIndex + 1}"));
            rehome:
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拉低信号  机器人程序启动，机器人停止", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                GlobalVariable.RobotControlStatus2[(int)RobotoutEnumRobot2.机器人程序启动] = false;
                GlobalVariable.RobotControlStatus2[(int)RobotoutEnumRobot2.机器人停止] = false;
                Thread.Sleep(200);
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拉高信号  机器人停止", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                GlobalVariable.RobotControlStatus2[(int)RobotoutEnumRobot2.机器人停止] = true;
                Thread.Sleep(200);
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拉高信号  机器人报警复位", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                GlobalVariable.RobotControlStatus2[(int)RobotoutEnumRobot2.机器人报警复位] = true;

                Thread.Sleep(500);
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拉低信号  机器人报警复位", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                GlobalVariable.RobotControlStatus2[(int)RobotoutEnumRobot2.机器人报警复位] = false;
                Thread.Sleep(500);

                if (!CheckFlowCondition()) return;
                //每次复位需要关闭TCP重新打开
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"关闭TCP", this.Description, 0, $"机械手{_moduleIndex + 1}"));

                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拉高信号  机器人程序复位", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                GlobalVariable.RobotControlStatus2[(int)RobotoutEnumRobot2.机器人程序复位] = true;
                Thread.Sleep(500);
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拉低信号  机器人程序复位", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                GlobalVariable.RobotControlStatus2[(int)RobotoutEnumRobot2.机器人程序复位] = false;
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拉高信号  机器人程序启动", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                GlobalVariable.RobotControlStatus2[(int)RobotoutEnumRobot2.机器人程序启动] = true;
                Thread.Sleep(200);
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拉低信号  机器人程序启动", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                GlobalVariable.RobotControlStatus2[(int)RobotoutEnumRobot2.机器人程序启动] = false;
                if (!CheckFlowCondition()) return;

                Thread.Sleep(2000);
                //等回零信号从OFF-->>ON 代表回零完成
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等回零信号从OFF-->>ON 代表回零完成", this.Description, 0, $"机械手{_moduleIndex + 1}"));
                var watch = Stopwatch.StartNew();
                if (!isSimulate)
                {
                    while (!GlobalVariable.RobotStatus2[(int)RobotinEnumRobot2.机器人回零完成] && !IsBreak())
                    {
                        Thread.Sleep(50);
                    }
                    if (!CheckFlowCondition()) return;
                    if (watch.ElapsedMilliseconds > 30000)
                    {
                        watch.Stop();
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Warn, $"机械手回零超时!", this.Description, 10, $"机械手{_moduleIndex + 1}"));
                        //出错，停下所有线程
                        _flowManager.Pause();
                        //若为报错，需重新检测启动信号
                        WaitForStart();
                        if (!CheckFlowCondition()) return;
                        goto rehome;
                    }
                    watch.Stop();
                }

                if (!CheckFlowCondition()) return;

                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"{this.Description} 回零完成!", this.Description, 0, $"机械手{_moduleIndex + 1}"));

                GlobalVariable.AlreadyOpenPrecisionFeedProductVacUp[0] = false;
                GlobalVariable.AlreadyGrabProductUp[0] = false;
                GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[0] = false;
                GlobalVariable.AlreadyOpenPrecisionFeedProductVacDown[0] = false;
                GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[0] = false;
                GlobalVariable.AlreadyOpenPrecisionFeedProductVacUp[1] = false;
                GlobalVariable.AlreadyGrabProductUp[1] = false;
                GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[1] = false;
                GlobalVariable.AlreadyOpenPrecisionFeedProductVacDown[1] = false;
                GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[1] = false;

                checkProductStatus();

                if (!CheckFlowCondition()) return;
                NotifyRobotSwitchProduct(_moduleIndex + 1);
                if (!CheckFlowCondition()) return;
                if (!GlobalVariable.HasNotifyRobotSwitch)
                {
                    ShowWarnAndPause("机械手2产品切换失败！", this.Description);
                }
                if (!CheckFlowCondition()) return;
            }

            _robotFeedTray.Helper.NewEmptyTray();
            _robotRecycleTray.Helper.NewEmptyTray();
            _robotTotalTray.Helper.NewEmptyTray();

            _feedHalfTray1.Helper.NewEmptyTray();
            _feedHalfTray2.Helper.NewEmptyTray();
            _recycleHalfTray1.Helper.NewEmptyTray();
            _recycleHalfTray2.Helper.NewEmptyTray();

            _status = RobotStatus.WaitTray;

            isAllPointsGot = false;
            pointStr = "";

            startRecvJDW = false;
            SecondJDWOKRecv = false;
            SecondJDWResult = false;
            JDWDetailCylinder = String.Empty;
            JDWPutDetailCylinder = String.Empty;
            JDWGetDetailCylinder = String.Empty;
            receivedStart = false;
            GlobalVariable.IsFristRunMachineFlagFront = true;
            GlobalVariable.IsFristRunMachineFlagBack = true;
            GlobalVariable.CTMachineMonitorFront.Stop();
            GlobalVariable.CTMachineMonitorBack.Stop();
            GlobalVariable.UPHListFront.Clear();
            GlobalVariable.UPHListBack.Clear();
            GlobalVariable.NeedRecycleEmptyBoatTray1 = false;
            GlobalVariable.NeedRecycleEmptyBoatTrayFinish1 = false;

            GlobalVariable.NeedRecycleEmptyBoatTray2 = false;
            GlobalVariable.NeedRecycleEmptyBoatTrayFinish2 = false;
            Speed = 0;
            Acc = 0;
            Dec = 0;
            _robot.EmptySendBuffer();
            CTMoveStopCalculateNode();
            SetSignal("回零完成");
        }
        public override void Init(out string errInfo)
        {
            if (_moduleIndex == 0)
            {
                GlobalVariable.RobotControlStatus[(int)RobotoutEnumRobot1.机器人停止] = true;
                GlobalVariable.RobotControlStatus[(int)RobotoutEnumRobot1.机器人紧急停止] = true;
            }
            else
            {
                GlobalVariable.RobotControlStatus2[(int)RobotoutEnumRobot2.机器人停止] = true;
                GlobalVariable.RobotControlStatus2[(int)RobotoutEnumRobot2.机器人紧急停止] = true;
            }
            base.Init(out errInfo);
        }
        Tray feedTray;
        public override void Method()
        {
            if (!CheckFlowCondition()) return;
            if (GlobalVariable.IsSpotChecking)
                return;

            switch (_status)
            {
                case RobotStatus.WaitTray:
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"{this.Description}进入WaitTray状态", this.Description, 0, ""));
                    if (_moduleIndex == 0)
                    {
                        while (!CheckSignal($"轨道拍照{_moduleIndex + 1}", "拍照完成") && !IsBreak() && !(GlobalVariable.IsClearNow || GlobalVariable.IsClearLater))
                        {
                            Thread.Sleep(20);
                        }
                        if (!CheckFlowCondition()) return;
                        if (!GlobalVariable.IsClearLater && !GlobalVariable.IsClearNow)
                            WaitForSignal($"轨道拍照{_moduleIndex + 1}", "拍照完成");
                    }
                    else
                    {
                        while (!CheckSignal($"轨道拍照{_moduleIndex + 1}", "拍照完成") && !IsBreak() && !(GlobalVariable.IsClearNow2 || GlobalVariable.IsClearLater2))
                        {
                            Thread.Sleep(20);
                        }
                        if (!CheckFlowCondition()) return;
                        if (!GlobalVariable.IsClearLater2 && !GlobalVariable.IsClearNow2)
                            WaitForSignal($"轨道拍照{_moduleIndex + 1}", "拍照完成");
                    }
                    feedTray = (_flowManager.SelectFlow($"轨道拍照{_moduleIndex + 1}") as CaptureTrayLogic).GetFeedTray();
                    _feedHalfTray1.Helper.NewFullTray();
                    _feedHalfTray2.Helper.NewFullTray();
                    _status = RobotStatus.GetTray;
                    break;

                case RobotStatus.GetTray:
                    SetRobotSpeed();
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"{this.Description}进入GetTray状态", this.Description, 0, ""));
                reget:
                    if ((GlobalVariable.IsClearNow && _moduleIndex == 0) ||
                        (GlobalVariable.IsClearNow2 && _moduleIndex == 1))
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前清料状态，直接让轨道进入PutGetPrecision状态", this.Description, 0, ""));
                        _status = RobotStatus.PutGetPrecision;
                    }
                    else
                    {
                        //这个只是通过2个half tray来判断的
                        (int, int) getIndex = GetFeedTrayGetIndex(out int getMode);
                        InSingleRunMode();
                        if (((getMode == -1 && !GlobalVariable.IsClearLater && _moduleIndex == 0) ||
                             (getMode == -1 && !GlobalVariable.IsClearLater2 && _moduleIndex == 1)) &&
                             !GlobalVariable.IsGrrMode &&
                             !GlobalVariable.IsCosmeticMode)
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"轨道feedtray的料都取完了", this.Description, 0, ""));
                            SetSignal("料取完");
                            if (_moduleIndex == 0)
                            {
                                if (GlobalVariable.IsClearLater)
                                {
                                    GlobalVariable.IsClearNow = true;
                                    _status = RobotStatus.PutGetPrecision;
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前由later清料状态进入真正清料状态，直接让轨道进入PutGetPrecision状态", this.Description, 0, ""));
                                }
                                else
                                {
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待轨道料盘过来", this.Description, 0, ""));
                                    _status = RobotStatus.WaitTray;
                                }
                            }
                            else
                            {
                                if (GlobalVariable.IsClearLater2)
                                {
                                    GlobalVariable.IsClearNow2 = true;
                                    _status = RobotStatus.PutGetPrecision;
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前由later清料状态进入真正清料状态，直接让轨道进入PutGetPrecision状态", this.Description, 0, ""));
                                }
                                else
                                {
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待轨道料盘过来", this.Description, 0, ""));
                                    _status = RobotStatus.WaitTray;
                                }
                            }
                        }
                        else if (getMode == -1)
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"轨道feedtray的料都取完了", this.Description, 0, ""));
                            if (_moduleIndex == 0)
                            {
                                if (GlobalVariable.IsClearLater)
                                {
                                    if (!GlobalVariable.IsClearNow)
                                        SetSignal("料取完");
                                    GlobalVariable.IsClearNow = true;
                                }
                            }
                            else
                            {
                                if (GlobalVariable.IsClearLater2)
                                {
                                    if (!GlobalVariable.IsClearNow2)
                                        SetSignal("料取完");
                                    GlobalVariable.IsClearNow2 = true;
                                }
                            }
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前处于later清料状态，直接让轨道进入PutGetPrecision状态", this.Description, 0, ""));
                            _status = RobotStatus.PutGetPrecision;
                        }
                        else
                        {
                            CTCalculateNode(out double ct);
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.CT, ct.ToString("0.0"), "", 0, "机械手CT"));
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"轨道有料可取，index:{getIndex}, mode:{getMode}", this.Description, 0, ""));
                            DateTime dateTime = DateTime.Now;
                            CTMoveStartCalculateNode();
                            RobotGetProduct(getIndex, getMode, out bool isSuccess, out bool isTrayEmpty);
                            if (isTrayEmpty)
                            {
                                if ((GlobalVariable.IsClearNow || GlobalVariable.IsClearLater) ||
                                   (GlobalVariable.IsClearNow2 || GlobalVariable.IsClearLater2) ||
                                   GlobalVariable.IsGrrMode ||
                                   GlobalVariable.IsCosmeticMode)
                                {
                                    if (GlobalVariable.IsGrrMode)
                                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前GRR模式或压测模式，直接让轨道进入PutGetPrecision状态", this.Description, 0, ""));
                                    else
                                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前清料状态，直接让轨道进入PutGetPrecision状态", this.Description, 0, ""));
                                    _status = RobotStatus.PutGetPrecision;
                                }
                                else
                                {
                                    _status = RobotStatus.WaitTray;
                                }
                            }
                            else
                            {
                                if (!isSuccess)
                                {
                                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取料失败，重复取料过程", this.Description, 0, ""));
                                    goto reget;
                                }
                                TimeSpan ts = DateTime.Now - dateTime;
                                CTMoveEndCalculateNode(out double time1);
                                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.CT, time1.ToString("0.0"), "", 0, $"机械手{_moduleIndex + 1}取料上料盘"));
                                LogHelper.Instance.Log(this.Description, $"机械手取料:{ts.Milliseconds}", MessageLevel.CT);
                                if (!CheckFlowCondition()) return;
                                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"手上有待测料，去取放精定位", this.Description, 0, ""));
                                _status = RobotStatus.PutGetPrecision;
                            }
                        }
                    }
                    break;

                case RobotStatus.PutGetPrecision:
                    SetRobotSpeed();
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"{this.Description}进入PutGetPrecision状态", this.Description, 0, ""));
                    WaitForSignal($"精定位移载{_moduleIndex + 1}", "机械手可放料");
                    if (!CheckFlowCondition()) return;
                    bool upReady = (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetTwoLayerInPositionStatusRobot();
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"当前轨道状态:{upReady}，开始取放精定位", this.Description, 0, ""));
                    RobotPutGetPrecision(upReady);
                    if (!CheckFlowCondition()) return;
                    InSingleRunMode();
                    SetSignal("放料完成");
                    if (_robotRecycleTray.Helper.Any(c => c.Status == CellStatus.HasProduct))
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"手上取到了OK料，要去下OK料", this.Description, 0, ""));
                        _status = RobotStatus.PutProduct;
                    }
                    else
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"没有OK料，还是去取料，此时可能手上已经有待测料了", this.Description, 0, ""));
                        _status = RobotStatus.GetTray;
                    }
                    break;

                case RobotStatus.PutProduct:
                    SetRobotSpeed();
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"{this.Description}进入PutProduct状态", this.Description, 0, ""));
                    Tray okTray1 = (_flowManager.SelectFlow($"轨道下料{_moduleIndex + 1}") as RecycleTrayLogic).GetOKTray1();
                    Tray okTray2 = (_flowManager.SelectFlow($"轨道下料{_moduleIndex + 1}") as RecycleTrayLogic).GetOKTray2();
                    //lock (GlobalVariable.OKTrayLock)
                    {
                        while ((okTray1.Helper.IsFull || okTray2.Helper.IsFull) && !IsBreak())
                        {
                            Thread.Sleep(20);
                        }
                    }
                    if (!CheckFlowCondition()) return;
                    if (okTray1.Helper.IsEmpty && okTray2.Helper.IsEmpty)
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"OKTray还没拍过照，先去拍照", this.Description, 0, ""));
                        if (!CaptureOKTray(_moduleIndex))
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"OKTray{_moduleIndex + 1}拍照失败,进行抛Tray", this.Description, 0, ""));
                            if (_moduleIndex == 0)
                            {
                                GlobalVariable.NeedRecycleEmptyBoatTray1 = true;
                                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待 OKTray{_moduleIndex + 1}拍照失败,进行抛Tray OK", this.Description, 0, ""));
                                while (!GlobalVariable.NeedRecycleEmptyBoatTrayFinish1 && !IsBreak())
                                {
                                    if (!CheckFlowCondition()) return;
                                    Thread.Sleep(2);
                                }
                                GlobalVariable.NeedRecycleEmptyBoatTrayFinish1 = false;
                            }
                            else
                            {
                                GlobalVariable.NeedRecycleEmptyBoatTray2 = true;
                                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待 OKTray{_moduleIndex + 1}拍照失败,进行抛Tray OK", this.Description, 0, ""));
                                while (!GlobalVariable.NeedRecycleEmptyBoatTrayFinish2 && !IsBreak())
                                {
                                    if (!CheckFlowCondition()) return;
                                    Thread.Sleep(2);
                                }
                                GlobalVariable.NeedRecycleEmptyBoatTrayFinish2 = false;
                            }
                            if (!CheckFlowCondition()) return;
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"OKTray{_moduleIndex + 1}拍照失败,进行抛Tray OK", this.Description, 0, ""));
                            break;
                        }
                        if (!CheckFlowCondition()) return;
                        _recycleHalfTray1.Helper.NewEmptyTray();
                        _recycleHalfTray2.Helper.NewEmptyTray();
                    }

                    #region 计算整线CTAndUPH
                    if (_moduleIndex == 0)
                    {
                        if (GlobalVariable.IsFristRunMachineFlagFront)
                        {
                            GlobalVariable.IsFristRunMachineFlagFront = false;
                            GlobalVariable.CTMachineMonitorFront.Restart();
                        }
                        else
                        {
                            GlobalVariable.CTMachineMonitorFront.Stop();
                            double ct = GlobalVariable.CTMachineMonitorFront.ElapsedMilliseconds / 1000.0;
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.CT, ct.ToString("0.00"), this.Description, 0, "FrontCT"));
                            GlobalVariable.CTMachineMonitorFront.Restart();
                            int count = 4;
                            GlobalVariable.UPHFront = (3600 / ct) * count;
                            double uph = 0;
                            lock (GlobalVariable.UPHLock)
                            {
                                if (GlobalVariable.UPHListFront.Count >= SystemConfig.Instance.TestParam.UPHCount)
                                {
                                    GlobalVariable.UPHListFront.RemoveAt(0);
                                }
                                GlobalVariable.UPHListFront.Add(GlobalVariable.UPHFront);
                                double uph1 = GlobalVariable.UPHListFront.Count > 0 ? GlobalVariable.UPHListFront.Average() : 0;
                                double uph2 = GlobalVariable.UPHListBack.Count > 0 ? GlobalVariable.UPHListBack.Average() : 0;
                                uph = uph1 + uph2;
                            }
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.CT, uph.ToString("0"), this.Description, 0, "UPH"));
                        }
                    }
                    else
                    {
                        if (GlobalVariable.IsFristRunMachineFlagBack)
                        {
                            GlobalVariable.IsFristRunMachineFlagBack = false;
                            GlobalVariable.CTMachineMonitorBack.Restart();
                        }
                        else
                        {
                            GlobalVariable.CTMachineMonitorBack.Stop();
                            double ct = GlobalVariable.CTMachineMonitorBack.ElapsedMilliseconds / 1000.0;
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.CT, ct.ToString("0.00"), this.Description, 0, "BackCT"));
                            GlobalVariable.CTMachineMonitorBack.Restart();
                            int count = 4;
                            GlobalVariable.UPHBack = (3600 / ct) * count;
                            double uph = 0;
                            lock (GlobalVariable.UPHLock)
                            {
                                if (GlobalVariable.UPHListBack.Count >= SystemConfig.Instance.TestParam.UPHCount)
                                {
                                    GlobalVariable.UPHListBack.RemoveAt(0);
                                }
                                GlobalVariable.UPHListBack.Add(GlobalVariable.UPHBack);
                                double uph1 = GlobalVariable.UPHListFront.Count > 0 ? GlobalVariable.UPHListFront.Average() : 0;
                                double uph2 = GlobalVariable.UPHListBack.Count > 0 ? GlobalVariable.UPHListBack.Average() : 0;
                                uph = uph1 + uph2;
                            }
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.CT, uph.ToString("0"), this.Description, 0, "UPH"));
                        }
                    }
                    #endregion

                    if (_moduleIndex == 0)
                    {
                        int putIndex2 = _recycleHalfTray2.Helper.GetFirstIndex(CellStatus.NoProduct);
                        DateTime startTime2 = DateTime.Now;
                        CTMoveStartCalculateNode();
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"下OK Boat2,index:{putIndex2}", this.Description, 0, ""));

                        bool isFrist = _robotRecycleTray.Helper.GetCell(1).Status == CellStatus.HasProduct || _robotRecycleTray.Helper.GetCell(3).Status == CellStatus.HasProduct;
                        bool hasPutTwoTray = _robotRecycleTray.Helper.GetCell(0).Status == CellStatus.HasProduct || _robotRecycleTray.Helper.GetCell(2).Status == CellStatus.HasProduct;

                        PutOKBoat2(putIndex2, okTray2, true, hasPutTwoTray);
                        CTMoveEndCalculateNode(out double t2);
                        TimeSpan ts2 = DateTime.Now - startTime2;
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.CT, t2.ToString("0.00"), "", 0, $"机械手{_moduleIndex + 1}第一次下料"));
                        LogHelper.Instance.Log(this.Description, $"放Boat2时间:{ts2.Milliseconds}", MessageLevel.CT);


                        int putIndex1 = _recycleHalfTray1.Helper.GetFirstIndex(CellStatus.NoProduct);
                        CTMoveStartCalculateNode();
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"下OK Boat1,index:{putIndex1}", this.Description, 0, ""));
                        PutOKBoat1(putIndex1, okTray1, !isFrist, false);
                        TimeSpan ts1 = DateTime.Now - startTime2;
                        CTMoveEndCalculateNode(out double t1);
                        LogHelper.Instance.Log(this.Description, $"放Boat1时间:{ts1.Milliseconds}", MessageLevel.CT);
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.CT, t1.ToString("0.0"), "", 0, $"机械手{_moduleIndex + 1}第二次下料"));
                        if (!CheckFlowCondition()) return;
                    }
                    else
                    {
                        int putIndex1 = _recycleHalfTray1.Helper.GetFirstIndex(CellStatus.NoProduct);
                        DateTime startTime1 = DateTime.Now;
                        CTMoveStartCalculateNode();
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"下OK Boat1,index:{putIndex1}", this.Description, 0, ""));

                        bool isFrist = _robotRecycleTray.Helper.GetCell(0).Status == CellStatus.HasProduct || _robotRecycleTray.Helper.GetCell(2).Status == CellStatus.HasProduct;
                        bool hasPutTwoTray = _robotRecycleTray.Helper.GetCell(1).Status == CellStatus.HasProduct || _robotRecycleTray.Helper.GetCell(3).Status == CellStatus.HasProduct;

                        PutOKBoat1(putIndex1, okTray1, true, hasPutTwoTray);
                        TimeSpan ts1 = DateTime.Now - startTime1;
                        CTMoveEndCalculateNode(out double t1);
                        LogHelper.Instance.Log(this.Description, $"放Boat1时间:{ts1.Milliseconds}", MessageLevel.CT);
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.CT, t1.ToString("0.0"), "", 0, $"机械手{_moduleIndex + 1}第一次下料"));
                        if (!CheckFlowCondition()) return;


                        int putIndex2 = _recycleHalfTray2.Helper.GetFirstIndex(CellStatus.NoProduct);
                        DateTime startTime2 = DateTime.Now;
                        CTMoveStartCalculateNode();
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"下OK Boat2,index:{putIndex2}", this.Description, 0, ""));
                        PutOKBoat2(putIndex2, okTray2, !isFrist, false);
                        CTMoveEndCalculateNode(out double t2);
                        TimeSpan ts2 = DateTime.Now - startTime1;
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.CT, t2.ToString("0.00"), "", 0, $"机械手{_moduleIndex + 1}第二次下料"));
                        LogHelper.Instance.Log(this.Description, $"放Boat2时间:{ts2.Milliseconds}", MessageLevel.CT);
                    }


                    if (!CheckFlowCondition()) return;
                    if (okTray1.Helper.IsFull || okTray2.Helper.IsFull)
                    {
                        //满料后 下料线程会自己下料
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"OK Tray都满了", this.Description, 0, ""));
                    }
                    _status = RobotStatus.GetTray;
                    break;
            }
        }

        private void SetRobotSpeed()
        {
            if (_moduleIndex == 0)
            {
                if (Speed != SystemConfig.Instance.UsingStatus.RobotSpeed1
                    || Acc != SystemConfig.Instance.UsingStatus.RobotAcc1
                    || Dec != SystemConfig.Instance.UsingStatus.RobotDec1)
                {
                    Speed = SystemConfig.Instance.UsingStatus.RobotSpeed1;
                    Acc = SystemConfig.Instance.UsingStatus.RobotAcc1;
                    Dec = SystemConfig.Instance.UsingStatus.RobotDec1;
                    RobotCommandRun($"SetSpeed,{Speed},{Acc},{Dec}", $"机械手{_moduleIndex + 1}设置速度失败!", out string recvStr1);
                }
            }
            else
            {
                if (Speed != SystemConfig.Instance.UsingStatus.RobotSpeed2
                       || Acc != SystemConfig.Instance.UsingStatus.RobotAcc2
                       || Dec != SystemConfig.Instance.UsingStatus.RobotDec2)
                {
                    Speed = SystemConfig.Instance.UsingStatus.RobotSpeed2;
                    Acc = SystemConfig.Instance.UsingStatus.RobotAcc2;
                    Dec = SystemConfig.Instance.UsingStatus.RobotDec2;
                    RobotCommandRun($"SetSpeed,{Speed},{Acc},{Dec}", $"机械手{_moduleIndex + 1}设置速度失败!", out string recvStr1);
                }
            }
        }

        public void Log(string str)
        {
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, str, this.Description, 0, ""));
        }
        public override void OnStop()
        {
            base.OnStop();
        }
        public override bool PreStartCheck()
        {
            return base.PreStartCheck();
        }
        public void RobotGetProduct((int, int) getIndex, int getMode, out bool isSuccess, out bool isTrayEmpty)
        {
            isSuccess = true;
            isTrayEmpty = false;
            //*****************************************
            //sts决定了发给机械手的哪几个吸嘴取料
            // 1,1,1,1 => 1 2 5 6 吸嘴
            // 12对应 robotfeedtray的12  56对应robotfeedtray的34
            //***********************************************
            List<int> sts = new List<int>();

            if (getMode == 3)
            {
                //3模式下，先12吸嘴取两颗，再移动下，56吸嘴取两颗
                if (getIndex.Item1 < 15)
                {
                    if (_moduleIndex == 0)
                    {
                        sts.Add(feedTray.Helper.GetCell(getIndex.Item1).Status == CellStatus.HasProduct ? 1 : 0);
                        sts.Add(feedTray.Helper.GetCell(getIndex.Item1 + 60).Status == CellStatus.HasProduct ? 1 : 0);
                    }
                    else
                    {
                        sts.Add(feedTray.Helper.GetCell(getIndex.Item1 + 60).Status == CellStatus.HasProduct ? 1 : 0);
                        sts.Add(feedTray.Helper.GetCell(getIndex.Item1).Status == CellStatus.HasProduct ? 1 : 0);
                    }
                    sts.Add(0);
                    sts.Add(0);
                }
                else
                {
                    if (_moduleIndex == 0)
                    {
                        sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1).Status == CellStatus.HasProduct ? 1 : 0);
                        sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1 + 60).Status == CellStatus.HasProduct ? 1 : 0);
                    }
                    else
                    {
                        sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1 + 60).Status == CellStatus.HasProduct ? 1 : 0);
                        sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1).Status == CellStatus.HasProduct ? 1 : 0);
                    }
                    sts.Add(0);
                    sts.Add(0);
                }
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"预取料状态为：{string.Join(",", sts)}", this.Description, 0, ""));
                //已经有料了，不要再取了
                if (_robotFeedTray.Helper.GetCell(0).Status == CellStatus.HasProduct)
                    sts[0] = 0;
                if (_robotFeedTray.Helper.GetCell(1).Status == CellStatus.HasProduct)
                    sts[1] = 0;
                if (_robotFeedTray.Helper.GetCell(2).Status == CellStatus.HasProduct)
                    sts[2] = 0;
                if (_robotFeedTray.Helper.GetCell(3).Status == CellStatus.HasProduct)
                    sts[3] = 0;
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"由于手上已经有料，实际取料状态为：{string.Join(",", sts)}", this.Description, 0, ""));
                //好歹也得有一颗料吧
                if (sts.Any(s => s == 1))
                {
                    lock (GlobalVariable.FrontBackInputDataLock)
                    {
                        GlobalVariable.CurrentMachineData.TotalInputCount += sts.Count(s => s == 1);
                    }
                    List<int> oldComm = sts;
                    GlobalVariable.SaveMachineData(GlobalVariable.CurrentMachineData);
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Count, GlobalVariable.CurrentMachineData.TotalInputCount.ToString(), this.Description, 0, "Input"));
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"手上至少还有一颗待测料要取，通知机械手去取料", this.Description, 0, ""));
                    if (isSimulate)
                    {
                        Thread.Sleep(1000);
                    }
                    else
                    {
                        //机器人去取料
                        //RobotCommandRun($"GetTray,{getIndex.Item1},{string.Join(",", sts)}", "机械手取料失败!", out string recvStr);

                        sts = RobotCommandRunAndOPCheck($"GetTray,{getIndex.Item1},{feedTransPositions[getIndex.Item1].X},{feedTransPositions[getIndex.Item1].Y},{feedTransPositions[getIndex.Item1].R}", sts, $"机械手{_moduleIndex + 1}上料Tray取料失败!", out string recvStr);
                        if (!CheckFlowCondition()) return;
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机器人{_moduleIndex + 1}模组:上料取料指令：{string.Join(",", oldComm)},选择：：{string.Join(",", sts)}", this.Description, 0, ""));

                    }
                    for (int i = 0; i < 4; i++)
                    {
                        //置位robotFeedTray的12，也就是12吸嘴
                        if (i == 0 && sts[0] == 1)
                            _robotFeedTray.Helper.SetCellStatus(0, CellStatus.HasProduct);
                        if (i == 1 && sts[1] == 1)
                            _robotFeedTray.Helper.SetCellStatus(1, CellStatus.HasProduct);
                        if (i == 2 && sts[2] == 1)
                            _robotFeedTray.Helper.SetCellStatus(2, CellStatus.HasProduct);
                        if (i == 3 && sts[3] == 1)
                            _robotFeedTray.Helper.SetCellStatus(3, CellStatus.HasProduct);

                        //界面刷新用
                        if (i == 0 && sts[i] == 1)
                            _robotTotalTray.Helper.SetCellStatus(3, CellStatus.HasProduct);
                        if (i == 1 && sts[i] == 1)
                            _robotTotalTray.Helper.SetCellStatus(7, CellStatus.HasProduct);
                        if (i == 2 && sts[i] == 1)
                            _robotTotalTray.Helper.SetCellStatus(1, CellStatus.HasProduct);
                        if (i == 3 && sts[i] == 1)
                            _robotTotalTray.Helper.SetCellStatus(5, CellStatus.HasProduct);
                    }
                    if (getIndex.Item1 < 15)
                    {
                        if (_moduleIndex == 0)
                        {
                            if (oldComm[0] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item1, CellStatus.NoProduct);
                            if (oldComm[1] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item1 + 60, CellStatus.NoProduct);
                            if (oldComm[2] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item1 + 15, CellStatus.NoProduct);
                            if (oldComm[3] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item1 + 60 + 15, CellStatus.NoProduct);
                        }
                        else
                        {
                            if (oldComm[0] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item1 + 60, CellStatus.NoProduct);
                            if (oldComm[1] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item1, CellStatus.NoProduct);
                            if (oldComm[2] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item1 + 60 + 15, CellStatus.NoProduct);
                            if (oldComm[3] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item1 + 15, CellStatus.NoProduct);
                        }
                    }
                    else
                    {
                        if (_moduleIndex == 0)
                        {
                            if (oldComm[0] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item1, CellStatus.NoProduct);
                            if (oldComm[1] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item1 + 60, CellStatus.NoProduct);
                            if (oldComm[2] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item1 + 15, CellStatus.NoProduct);
                            if (oldComm[3] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item1 + 60 + 15, CellStatus.NoProduct);
                        }
                        else
                        {
                            if (oldComm[0] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item1 + 60, CellStatus.NoProduct);
                            if (oldComm[1] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item1, CellStatus.NoProduct);
                            if (oldComm[2] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item1 + 60 + 15, CellStatus.NoProduct);
                            if (oldComm[3] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item1 + 15, CellStatus.NoProduct);
                        }
                    }
                    if (oldComm[0] == 1 && oldComm[1] == 1)
                        _feedHalfTray1.Helper.SetCellStatus(getIndex.Item1, CellStatus.NoProduct);
                    if (oldComm[2] == 1 && oldComm[3] == 1)
                        _feedHalfTray2.Helper.SetCellStatus(getIndex.Item1, CellStatus.NoProduct);
                }

                sts = new List<int>();
                //取后面2颗
                if (getIndex.Item2 < 15)
                {
                    sts.Add(0);
                    sts.Add(0);
                    if (_moduleIndex == 0)
                    {
                        sts.Add(feedTray.Helper.GetCell(getIndex.Item2 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                        sts.Add(feedTray.Helper.GetCell(getIndex.Item2 + 60 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                    }
                    else
                    {
                        sts.Add(feedTray.Helper.GetCell(getIndex.Item2 + 60 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                        sts.Add(feedTray.Helper.GetCell(getIndex.Item2 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                    }
                }
                else
                {
                    sts.Add(0);
                    sts.Add(0);
                    if (_moduleIndex == 0)
                    {
                        sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item2 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                        sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item2 + 60 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                    }
                    else
                    {
                        sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item2 + 60 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                        sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item2 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                    }
                }
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"预取料状态为：{string.Join(",", sts)}", this.Description, 0, ""));
                //已经有料了，不要再取了
                if (_robotFeedTray.Helper.GetCell(0).Status == CellStatus.HasProduct)
                    sts[0] = 0;
                if (_robotFeedTray.Helper.GetCell(1).Status == CellStatus.HasProduct)
                    sts[1] = 0;
                if (_robotFeedTray.Helper.GetCell(2).Status == CellStatus.HasProduct)
                    sts[2] = 0;
                if (_robotFeedTray.Helper.GetCell(3).Status == CellStatus.HasProduct)
                    sts[3] = 0;
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"由于手上已经有料，实际取料状态为：{string.Join(",", sts)}", this.Description, 0, ""));
                //好歹也得有一颗料吧
                if (sts.Any(s => s == 1))
                {
                    List<int> oldComm = sts;
                    GlobalVariable.CurrentMachineData.TotalInputCount += sts.Count(s => s == 1);
                    GlobalVariable.SaveMachineData(GlobalVariable.CurrentMachineData);
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Count, GlobalVariable.CurrentMachineData.TotalInputCount.ToString(), this.Description, 0, "Input"));
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"手上至少还有一颗待测料要取，通知机械手去取料", this.Description, 0, ""));
                    if (isSimulate)
                    {
                        Thread.Sleep(1000);
                    }
                    else
                    {
                        //机器人去取料
                        ////RobotCommandRun($"GetTray,{getIndex.Item2},{feedTransPositions[getIndex.Item2].X},{feedTransPositions[getIndex.Item2].Y},{feedTransPositions[getIndex.Item2].R},{string.Join(",", sts)}", "机械手取料失败!", out string recvStr);

                        sts = RobotCommandRunAndOPCheck($"GetTray,{getIndex.Item2},{feedTransPositions[getIndex.Item2].X},{feedTransPositions[getIndex.Item2].Y},{feedTransPositions[getIndex.Item2].R}", sts, $"机械手{_moduleIndex + 1}上料Tray取料失败!", out string recvStr);
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机器人{_moduleIndex + 1}模组:上料取料指令：{string.Join(",", oldComm)},选择：：{string.Join(",", sts)}", this.Description, 0, ""));
                        if (!CheckFlowCondition()) return;
                    }
                    for (int i = 0; i < 4; i++)
                    {
                        //置位robotFeedTray的34，也就是56吸嘴
                        if (i == 0 && sts[0] == 1)
                            _robotFeedTray.Helper.SetCellStatus(0, CellStatus.HasProduct);
                        if (i == 1 && sts[1] == 1)
                            _robotFeedTray.Helper.SetCellStatus(1, CellStatus.HasProduct);
                        if (i == 2 && sts[2] == 1)
                            _robotFeedTray.Helper.SetCellStatus(2, CellStatus.HasProduct);
                        if (i == 3 && sts[3] == 1)
                            _robotFeedTray.Helper.SetCellStatus(3, CellStatus.HasProduct);
                        if (i == 0 && sts[i] == 1)
                            _robotTotalTray.Helper.SetCellStatus(3, CellStatus.HasProduct);
                        if (i == 1 && sts[i] == 1)
                            _robotTotalTray.Helper.SetCellStatus(7, CellStatus.HasProduct);
                        if (i == 2 && sts[i] == 1)
                            _robotTotalTray.Helper.SetCellStatus(1, CellStatus.HasProduct);
                        if (i == 3 && sts[i] == 1)
                            _robotTotalTray.Helper.SetCellStatus(5, CellStatus.HasProduct);
                    }
                    if (getIndex.Item2 < 15)
                    {
                        if (_moduleIndex == 0)
                        {
                            if (oldComm[0] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item2, CellStatus.NoProduct);
                            if (oldComm[1] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item2 + 60, CellStatus.NoProduct);
                            if (oldComm[2] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item2 + 15, CellStatus.NoProduct);
                            if (oldComm[3] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item2 + 60 + 15, CellStatus.NoProduct);
                        }
                        else
                        {
                            if (oldComm[0] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item2 + 60, CellStatus.NoProduct);
                            if (oldComm[1] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item2, CellStatus.NoProduct);
                            if (oldComm[2] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item2 + 60 + 15, CellStatus.NoProduct);
                            if (oldComm[3] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item2 + 15, CellStatus.NoProduct);
                        }
                    }
                    else
                    {
                        if (_moduleIndex == 0)
                        {
                            if (oldComm[0] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item2, CellStatus.NoProduct);
                            if (oldComm[1] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item2 + 60, CellStatus.NoProduct);
                            if (oldComm[2] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item2 + 15, CellStatus.NoProduct);
                            if (oldComm[3] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item2 + 60 + 15, CellStatus.NoProduct);
                        }
                        else
                        {
                            if (oldComm[0] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item2 + 60, CellStatus.NoProduct);
                            if (oldComm[1] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item2, CellStatus.NoProduct);
                            if (oldComm[2] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item2 + 60 + 15, CellStatus.NoProduct);
                            if (oldComm[3] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item2 + 15, CellStatus.NoProduct);
                        }
                    }
                    if (oldComm[0] == 1 && oldComm[1] == 1)
                        _feedHalfTray1.Helper.SetCellStatus(getIndex.Item2, CellStatus.NoProduct);
                    if (oldComm[2] == 1 && oldComm[3] == 1)
                        _feedHalfTray2.Helper.SetCellStatus(getIndex.Item2, CellStatus.NoProduct);

                    //再次判断料是否取完
                    getIndex = GetFeedTrayGetIndex(out getMode);
                    if (getMode < 0)
                    {
                        if (_moduleIndex == 0)
                        {
                            isTrayEmpty = true;
                            if (!(GlobalVariable.IsClearLater || GlobalVariable.IsClearNow) &&
                                !GlobalVariable.IsGrrMode && !GlobalVariable.IsCosmeticMode)
                            {
                                SetSignal("料取完");
                            }
                        }
                        else
                        {
                            isTrayEmpty = true;
                            if (!(GlobalVariable.IsClearLater2 || GlobalVariable.IsClearNow2) &&
                                !GlobalVariable.IsGrrMode && !GlobalVariable.IsCosmeticMode)
                            {
                                SetSignal("料取完");
                            }
                        }
                    }
                    if (isSimulate)
                    {
                        Thread.Sleep(2000);
                    }
                }

                if (!(_robotFeedTray.Helper.Any(c => c.Status == CellStatus.HasProduct)))
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"无料可取，手上也没有待测料残余，取料失败", this.Description, 0, ""));
                    //取不到 料，因为这波没得取
                    isSuccess = false;
                }
            }
            else
            {
                //只取2颗  12吸嘴取
                if (getMode == 0)
                {
                    if (getIndex.Item1 < 15)
                    {
                        if (_moduleIndex == 0)
                        {
                            sts.Add(feedTray.Helper.GetCell(getIndex.Item1).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(getIndex.Item1 + 60).Status == CellStatus.HasProduct ? 1 : 0);
                        }
                        else
                        {
                            sts.Add(feedTray.Helper.GetCell(getIndex.Item1 + 60).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(getIndex.Item1).Status == CellStatus.HasProduct ? 1 : 0);
                        }
                        sts.Add(0);
                        sts.Add(0);
                    }
                    else
                    {
                        if (_moduleIndex == 0)
                        {
                            sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1 + 60).Status == CellStatus.HasProduct ? 1 : 0);
                        }
                        else
                        {
                            sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1 + 60).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1).Status == CellStatus.HasProduct ? 1 : 0);
                        }
                        sts.Add(0);
                        sts.Add(0);
                    }
                }
                else if (getMode == 1)
                {
                    if (getIndex.Item1 < 15)
                    {
                        sts.Add(0);
                        sts.Add(0);
                        if (_moduleIndex == 0)
                        {
                            sts.Add(feedTray.Helper.GetCell(getIndex.Item1 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(getIndex.Item1 + 60 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                        }
                        else
                        {
                            sts.Add(feedTray.Helper.GetCell(getIndex.Item1 + 60 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(getIndex.Item1 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                        }
                    }
                    else
                    {
                        sts.Add(0);
                        sts.Add(0);
                        if (_moduleIndex == 0)
                        {
                            sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1 + 60 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                        }
                        else
                        {
                            sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1 + 60 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                        }
                    }
                }
                else if (getMode == 2)
                {
                    if (getIndex.Item1 < 15)
                    {
                        if (_moduleIndex == 0)
                        {
                            //根据当前料的状态来确定取料的吸嘴
                            sts.Add(feedTray.Helper.GetCell(getIndex.Item1).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(getIndex.Item1 + 60).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(getIndex.Item1 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(getIndex.Item1 + 60 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                        }
                        else
                        {
                            //根据当前料的状态来确定取料的吸嘴
                            sts.Add(feedTray.Helper.GetCell(getIndex.Item1 + 60).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(getIndex.Item1).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(getIndex.Item1 + 60 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(getIndex.Item1 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                        }
                    }
                    else
                    {
                        if (_moduleIndex == 0)
                        {
                            sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1 + 60).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1 + 60 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                        }
                        else
                        {
                            sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1 + 60).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1 + 60 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                            sts.Add(feedTray.Helper.GetCell(15 + getIndex.Item1 + 15).Status == CellStatus.HasProduct ? 1 : 0);
                        }
                    }
                }
                else
                {
                    ShowWarnAndPause("逻辑错误", "");
                }
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"预取料状态为：{string.Join(",", sts)}", this.Description, 0, ""));
                //已经有料了，不要再取了
                //
                if (_robotFeedTray.Helper.GetCell(0).Status == CellStatus.HasProduct)
                    sts[0] = 0;
                if (_robotFeedTray.Helper.GetCell(1).Status == CellStatus.HasProduct)
                    sts[1] = 0;
                if (_robotFeedTray.Helper.GetCell(2).Status == CellStatus.HasProduct)
                    sts[2] = 0;
                if (_robotFeedTray.Helper.GetCell(3).Status == CellStatus.HasProduct)
                    sts[3] = 0;

                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"由于手上已经有料，实际取料状态为：{string.Join(",", sts)}", this.Description, 0, ""));
                //好歹也得有一颗料吧
                if (sts.Any(s => s == 1))
                {
                    List<int> oldComm = sts;
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"手上至少还有一颗待测料要取，通知机械手去取料", this.Description, 0, ""));
                    if (isSimulate)
                    {
                        Thread.Sleep(1000);
                    }
                    else
                    {
                        //机器人去取料
                        //getIndex.Item1 = 29;
                        //RobotCommandRun($"GetTray,{getIndex.Item1},{feedTransPositions[getIndex.Item1].X},{feedTransPositions[getIndex.Item1].Y},{feedTransPositions[getIndex.Item1].R},{string.Join(",", sts)}", "机械手取料失败!", out string recvStr);
                        //if (!CheckFlowCondition()) return;
                        sts = RobotCommandRunAndOPCheck($"GetTray,{getIndex.Item1},{feedTransPositions[getIndex.Item1].X},{feedTransPositions[getIndex.Item1].Y},{feedTransPositions[getIndex.Item1].R}", sts, $"机械手{_moduleIndex + 1}上料Tray取料失败!", out string recvStr);
                        if (!CheckFlowCondition()) return;
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机器人{_moduleIndex + 1}模组:上料取料指令：{string.Join(",", oldComm)},选择：：{string.Join(",", sts)}", this.Description, 0, ""));

                    }
                    GlobalVariable.CurrentMachineData.TotalInputCount += sts.Count(s => s == 1);
                    GlobalVariable.SaveMachineData(GlobalVariable.CurrentMachineData);
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Count, GlobalVariable.CurrentMachineData.TotalInputCount.ToString(), this.Description, 0, "Input"));
                    for (int i = 0; i < 4; i++)
                    {
                        if (i == 0 && sts[0] == 1)
                            _robotFeedTray.Helper.SetCellStatus(0, CellStatus.HasProduct);
                        if (i == 1 && sts[1] == 1)
                            _robotFeedTray.Helper.SetCellStatus(1, CellStatus.HasProduct);
                        if (i == 2 && sts[2] == 1)
                            _robotFeedTray.Helper.SetCellStatus(2, CellStatus.HasProduct);
                        if (i == 3 && sts[3] == 1)
                            _robotFeedTray.Helper.SetCellStatus(3, CellStatus.HasProduct);
                        if (i == 0 && sts[i] == 1)
                            _robotTotalTray.Helper.SetCellStatus(3, CellStatus.HasProduct);
                        if (i == 1 && sts[i] == 1)
                            _robotTotalTray.Helper.SetCellStatus(7, CellStatus.HasProduct);
                        if (i == 2 && sts[i] == 1)
                            _robotTotalTray.Helper.SetCellStatus(1, CellStatus.HasProduct);
                        if (i == 3 && sts[i] == 1)
                            _robotTotalTray.Helper.SetCellStatus(5, CellStatus.HasProduct);
                    }
                    if (getIndex.Item1 < 15)
                    {
                        if (_moduleIndex == 0)
                        {
                            if (oldComm[0] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item1, CellStatus.NoProduct);
                            if (oldComm[1] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item1 + 60, CellStatus.NoProduct);
                            if (oldComm[2] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item1 + 15, CellStatus.NoProduct);
                            if (oldComm[3] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item1 + 60 + 15, CellStatus.NoProduct);
                        }
                        else
                        {
                            if (oldComm[1] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item1, CellStatus.NoProduct);
                            if (oldComm[0] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item1 + 60, CellStatus.NoProduct);
                            if (oldComm[3] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item1 + 15, CellStatus.NoProduct);
                            if (oldComm[2] == 1)
                                feedTray.Helper.SetCellStatus(getIndex.Item1 + 60 + 15, CellStatus.NoProduct);
                        }
                    }
                    else
                    {
                        if (_moduleIndex == 0)
                        {
                            if (oldComm[0] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item1, CellStatus.NoProduct);
                            if (oldComm[1] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item1 + 60, CellStatus.NoProduct);
                            if (oldComm[2] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item1 + 15, CellStatus.NoProduct);
                            if (oldComm[3] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item1 + 60 + 15, CellStatus.NoProduct);
                        }
                        else
                        {
                            if (oldComm[1] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item1, CellStatus.NoProduct);
                            if (oldComm[0] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item1 + 60, CellStatus.NoProduct);
                            if (oldComm[3] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item1 + 15, CellStatus.NoProduct);
                            if (oldComm[2] == 1)
                                feedTray.Helper.SetCellStatus(15 + getIndex.Item1 + 60 + 15, CellStatus.NoProduct);
                        }
                    }
                    if (oldComm[0] == 1 && oldComm[1] == 1)
                        _feedHalfTray1.Helper.SetCellStatus(getIndex.Item1, CellStatus.NoProduct);
                    if (oldComm[2] == 1 && oldComm[3] == 1)
                        _feedHalfTray2.Helper.SetCellStatus(getIndex.Item1, CellStatus.NoProduct);
                    //再次判断料是否取完
                    getIndex = GetFeedTrayGetIndex(out getMode);
                    if (getMode < 0)
                    {
                        if (_moduleIndex == 0)
                        {
                            isTrayEmpty = true;
                            if (!(GlobalVariable.IsClearLater || GlobalVariable.IsClearNow) &&
                                !GlobalVariable.IsGrrMode && !GlobalVariable.IsCosmeticMode)
                            {
                                SetSignal("料取完");
                            }
                        }
                        else
                        {
                            isTrayEmpty = true;
                            if (!(GlobalVariable.IsClearLater2 || GlobalVariable.IsClearNow2) &&
                                !GlobalVariable.IsGrrMode && !GlobalVariable.IsCosmeticMode)
                            {
                                SetSignal("料取完");
                            }
                        }
                    }
                    if (isSimulate)
                    {
                        Thread.Sleep(2000);
                    }
                }
                else if (_robotFeedTray.Helper.Any(c => c.Status == CellStatus.HasProduct))
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手不需要取料，但手上还是有待测料的，上轮残留，所以，继续放料去", this.Description, 0, ""));
                }
                else
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"无料可取，手上也没有待测料残余，取料失败", this.Description, 0, ""));
                    if (!feedTray.Helper.Any(c => c.Status == CellStatus.HasProduct))
                    {
                        isTrayEmpty = true;
                        if (_moduleIndex == 0)
                        {
                            isTrayEmpty = true;
                            if (!(GlobalVariable.IsClearLater || GlobalVariable.IsClearNow) &&
                                !GlobalVariable.IsGrrMode && !GlobalVariable.IsCosmeticMode)
                            {
                                SetSignal("料取完");
                            }
                        }
                        else
                        {
                            isTrayEmpty = true;
                            if (!(GlobalVariable.IsClearLater2 || GlobalVariable.IsClearNow2) &&
                                !GlobalVariable.IsGrrMode && !GlobalVariable.IsCosmeticMode)
                            {
                                SetSignal("料取完");
                            }
                        }
                    }
                    //取不到 料，因为这波没得取
                    isSuccess = false;
                }
            }
        }
        public void RobotPutGetPrecision(bool isUp)
        {
            //精定位的feedTray1对应供的是Arm1或3，对应的精定位穴位号是 56
            //精定位的feedTray2对应供的是Arm2或4，对应的精定位穴位号是 12
            //精定位的recycleTray1对应供的是Arm1或3，对应的精定位穴位号是 78
            //精定位的recycleTray2对应供的是Arm2或4，对应的精定位穴位号是 34
            Tray precisionRecycleTray1 = isUp ? (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetRecycleTray1Up() : (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetRecycleTray1Down();
            Tray precisionRecycleTray2 = isUp ? (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetRecycleTray2Up() : (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetRecycleTray2Down();
            Tray precisionFeedTray1 = isUp ? (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetFeedTray1Up() : (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetFeedTray1Down();
            Tray precisionFeedTray2 = isUp ? (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetFeedTray2Up() : (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetFeedTray2Down();

            if (precisionRecycleTray1.Helper.Any(c => c.Status == CellStatus.HasProduct) ||
                precisionRecycleTray2.Helper.Any(c => c.Status == CellStatus.HasProduct))
            {
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"精定位有OK料要回收", this.Description, 0, ""));
                InSingleRunMode();
                if (_robotFeedTray.Helper.Any(c => c.Status == CellStatus.HasProduct))
                {
                    safetyCheck(isUp);
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手有待测料要放精定位", this.Description, 0, ""));
                    DateTime dateTime = DateTime.Now;
                    CTMoveStartCalculateNode();
                    //if (_moduleIndex == 0)
                    //{
                    //    GetPutPrecision(isUp,
                    //               precisionRecycleTray1,
                    //               precisionRecycleTray2,
                    //               precisionFeedTray1,
                    //               precisionFeedTray2);
                    //}
                    //else
                    {
                        GetPutPrecisionInDoubleCylinder(isUp,
                                       precisionRecycleTray1,
                                       precisionRecycleTray2,
                                       precisionFeedTray1,
                                       precisionFeedTray2);
                    }
                    TimeSpan ts = DateTime.Now - dateTime;
                    CTMoveEndCalculateNode(out double t1);
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.CT, t1.ToString("0.0"), "", 0, $"精定位{_moduleIndex + 1}取放料"));
                    LogHelper.Instance.Log(this.Description, $"机械手取放精定位:{ts.Milliseconds}", MessageLevel.CT);
                    if (!CheckFlowCondition()) return;
                }
                else
                {
                    safetyCheck(isUp);
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手没有待测料，只取精定位", this.Description, 0, ""));
                    DateTime dateTime = DateTime.Now;
                    //if (_moduleIndex == 0)
                    //{
                    //    GetPrecision(isUp,
                    //             precisionRecycleTray1,
                    //             precisionRecycleTray2);
                    //}
                    //else
                    {
                        GetPrecisionInDoubleCylinder(isUp,
                                 precisionRecycleTray1,
                                 precisionRecycleTray2);
                    }
                    TimeSpan ts = DateTime.Now - dateTime;
                    LogHelper.Instance.Log(this.Description, $"机械手取精定位:{ts.Milliseconds}", MessageLevel.CT);
                    if (!CheckFlowCondition()) return;
                }
                InSingleRunMode();
            }
            else
            {
                InSingleRunMode();
                if (_robotFeedTray.Helper.Any(c => c.Status == CellStatus.HasProduct))
                {
                    safetyCheck(isUp);
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手只有待测料要放精定位，没有OK料要取", this.Description, 0, ""));
                    DateTime dateTime = DateTime.Now;
                    //if (_moduleIndex == 0)
                    //    PutPrecision(isUp, precisionFeedTray1, precisionFeedTray2);
                    //else
                    PutPrecisionInDoubleCylinder(isUp, precisionFeedTray1, precisionFeedTray2);
                    TimeSpan ts = DateTime.Now - dateTime;
                    LogHelper.Instance.Log(this.Description, $"机械手放精定位:{ts.Milliseconds}", MessageLevel.CT);
                    if (!CheckFlowCondition()) return;
                }
                else
                {
                    //ShowWarnAndPause("逻辑错误", "");
                }
                InSingleRunMode();
            }
        }
        //***********************************************
        //recyle 和 feed的 1 都是供 左边    2 都是供右边
        // fee1也即精定位的56 - 供左边Arm  feed2 精定位的12 - 供右边Arm
        // 对应的是robotfeedTray的34     和    12
        //***********************************************
        public void GetPutPrecision(bool isUp, Tray recycle1, Tray recycle2, Tray feed1, Tray feed2)
        {
            List<int> feedSts = _robotFeedTray.Helper.Select(c => c.Status == CellStatus.HasProduct ? 1 : 0).ToList();
            //if (_moduleIndex == 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    if (feed2.Helper.GetCell(i).Status == CellStatus.HasProduct)
                        feedSts[i] = 0;
                }
                for (int i = 0; i < 2; i++)
                {
                    if (feed1.Helper.GetCell(i).Status == CellStatus.HasProduct)
                        feedSts[i + 2] = 0;
                }
            }

            List<int> getSts = new List<int>();
            //if (_moduleIndex == 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    if (recycle2.Helper.GetCell(i).Status == CellStatus.HasProduct)
                        getSts.Add(1);
                    else
                        getSts.Add(0);
                }
                for (int i = 0; i < 2; i++)
                {
                    if (recycle1.Helper.GetCell(i).Status == CellStatus.HasProduct)
                        getSts.Add(1);
                    else
                        getSts.Add(0);
                }
            }
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取放精定位的状态为：{string.Join(",", feedSts)}{string.Join(",", getSts)}", this.Description, 0, ""));
            if (isSimulate)
            {
                Thread.Sleep(1000);
            }
            else
            {
                //机器人去取放料
                string HL = isUp ? "H" : "L";
                TcpClientSend(_robot, new SendPackage() { Message = $"JDW,{HL},{string.Join(",", getSts)},{string.Join(",", feedSts)},\r\n" });
                if (!CheckFlowCondition()) return;
                int count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
            wait1:
                //等待接收第二次精定位OK的标志
                startRecvJDW = true;
                JDWDetailCylinder = String.Empty;
                while (!SecondJDWOKRecv && !IsBreak())
                {
                    Thread.Sleep(20);
                }
                if (!CheckFlowCondition()) return;
                SecondJDWOKRecv = false;
                if (!SecondJDWResult)
                {
                    count--;
                    startRecvJDW = true;
                    if (count >= 0)
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}取精定位失败{JDWDetailCylinder} {count}次!", this.Description, 0, ""));
                    }
                    else
                    {
                        count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                        ShowWarnAndPause($"机械手{_moduleIndex + 1}取精定位失败{JDWDetailCylinder}!", this.Description);
                    }
                    if (!CheckFlowCondition()) return;
                    goto wait1;
                }

                int statusIndex = 0;
                if (_moduleIndex == 0)
                    statusIndex = 0;
                else if (_moduleIndex == 1)
                    statusIndex = 1;
                if (isUp)
                {
                    //等待接收第二次精定位OK的标志
                    startRecvJDW = true;
                    JDWDetailCylinder = String.Empty;
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待请求开真空信号", this.Description, 0, ""));
                    while (!GlobalVariable.NeedOpenPrecisionFeedProductVacUp[statusIndex] && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"拿到请求开真空信号", this.Description, 0, ""));
                    DoPrecisionCylinder(isFeed: true, isUp: isUp, isClamp: true);
                    //List<bool> vacStatus = feedSts.Select(s => s == 1).ToList();
                    //for (int i = 0; i < vacStatus.Count; i++)
                    //{
                    //    if (vacStatus[0])
                    //        _upVacs[0].On();
                    //    if (vacStatus[1])
                    //        _upVacs[1].On();
                    //    if (vacStatus[2])
                    //        _upVacs[4].On();
                    //    if (vacStatus[3])
                    //        _upVacs[5].On();
                    //}
                    if (!CheckFlowCondition()) return;
                    GlobalVariable.AlreadyOpenPrecisionFeedProductVacUp[statusIndex] = true;
                wait2:
                    //等机械手真空达到
                    while (!SecondJDWOKRecv && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    SecondJDWOKRecv = false;
                    if (!SecondJDWResult)
                    {
                        count--;
                        startRecvJDW = true;
                        if (count >= 0)
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}取精定位失败{JDWDetailCylinder} {count}次!", this.Description, 0, ""));
                        }
                        else
                        {
                            count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                            ShowWarnAndPause($"机械手{_moduleIndex + 1}取精定位失败{JDWDetailCylinder}!", this.Description);
                        }
                        if (!CheckFlowCondition()) return;
                        goto wait2;
                    }
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待请求关真空信号", this.Description, 0, ""));
                    while (!GlobalVariable.NeedClosePrecisionRecycleProductVacUp[statusIndex] && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"收到请求关真空信号", this.Description, 0, ""));
                    DoPrecisionCylinder(isFeed: false, isUp: isUp, isClamp: false);
                    //for (int i = 0; i < getSts.Count; i++)
                    //{
                    //    if (getSts[0] == 1)
                    //        _upVacs[2].Off();
                    //    if (getSts[1] == 1)
                    //        _upVacs[3].Off();
                    //    if (getSts[2] == 1)
                    //        _upVacs[6].Off();
                    //    if (getSts[3] == 1)
                    //        _upVacs[7].Off();
                    //}
                    GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[statusIndex] = true;

                    //等待气缸抬起
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待气缸抬起", this.Description, 0, ""));
                    while (!GlobalVariable.NozzleAlreadyLiftUp[statusIndex] && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    DoPrecisionCylinder(isFeed: true, isUp: isUp, isClamp: true, isDelay: false, isEnable: false);
                    GlobalVariable.AlreadyGrabProductUp[statusIndex] = true;

                    //等待接收第二次精定位OK的标志
                    startRecvJDW = true;
                    JDWDetailCylinder = String.Empty;
                    while (!SecondJDWOKRecv && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    SecondJDWOKRecv = false;
                    if (!SecondJDWResult)
                    {
                        count--;
                        startRecvJDW = true;
                        GlobalVariable.AlreadyGrabProductUp[statusIndex] = false;
                        GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[statusIndex] = false;
                        if (count >= 0)
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}取精定位失败{JDWDetailCylinder} {count}次!", this.Description, 0, ""));
                        }
                        else
                        {
                            count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                            ShowWarnAndPause($"机械手{_moduleIndex + 1}取精定位失败{JDWDetailCylinder}!", this.Description);
                        }
                        if (!CheckFlowCondition()) return;
                        goto wait2;
                    }

                    //MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待信号复位", this.Description, 0, ""));
                    //while (GlobalVariable.NeedClosePrecisionRecycleProductVacUp[statusIndex] && !IsBreak())
                    //{
                    //    Thread.Sleep(20);
                    //}
                    //if (!CheckFlowCondition()) return;
                    GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[statusIndex] = false;

                    //while (GlobalVariable.NeedOpenPrecisionFeedProductVacUp[statusIndex] && !IsBreak())
                    //{
                    //    Thread.Sleep(20);
                    //}
                    //if (!CheckFlowCondition()) return;
                    GlobalVariable.AlreadyOpenPrecisionFeedProductVacUp[statusIndex] = false;

                    GlobalVariable.AlreadyGrabProductUp[statusIndex] = false;
                    //MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"收到信号复位", this.Description, 0, ""));

                }
                else
                {
                    //等待接收第二次精定位OK的标志
                    startRecvJDW = true;
                    JDWDetailCylinder = String.Empty;
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待开真空信号", this.Description, 0, ""));
                    while (!GlobalVariable.NeedOpenPrecisionFeedProductVacDown[statusIndex] && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"收到开真空信号", this.Description, 0, ""));
                    DoPrecisionCylinder(isFeed: true, isUp: isUp, isClamp: true);
                    //List<bool> vacStatus = feedSts.Select(s => s == 1).ToList();
                    //for (int i = 0; i < vacStatus.Count; i++)
                    //{
                    //    if (vacStatus[0])
                    //        _downVacs[0].On();
                    //    if (vacStatus[1])
                    //        _downVacs[1].On();
                    //    if (vacStatus[2])
                    //        _downVacs[4].On();
                    //    if (vacStatus[3])
                    //        _downVacs[5].On();
                    //}
                    if (!CheckFlowCondition()) return;
                    GlobalVariable.AlreadyOpenPrecisionFeedProductVacDown[statusIndex] = true;

                wait2:
                    while (!SecondJDWOKRecv && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    SecondJDWOKRecv = false;
                    if (!SecondJDWResult)
                    {
                        count--;
                        startRecvJDW = true;
                        if (count >= 0)
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}取精定位失败{JDWDetailCylinder} {count}次!", this.Description, 0, ""));
                        }
                        else
                        {
                            count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                            ShowWarnAndPause($"机械手{_moduleIndex + 1}取精定位失败{JDWDetailCylinder}!", this.Description);
                        }
                        if (!CheckFlowCondition()) return;
                        goto wait2;
                    }
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待关真空信号", this.Description, 0, ""));
                    while (!GlobalVariable.NeedClosePrecisionRecycleProductVacDown[statusIndex] && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"收到关真空信号", this.Description, 0, ""));
                    DoPrecisionCylinder(isFeed: false, isUp: isUp, isClamp: false);
                    //for (int i = 0; i < getSts.Count; i++)
                    //{
                    //    if (getSts[0] == 1)
                    //        _downVacs[2].Off();
                    //    if (getSts[1] == 1)
                    //        _downVacs[3].Off();
                    //    if (getSts[2] == 1)
                    //        _downVacs[6].Off();
                    //    if (getSts[3] == 1)
                    //        _downVacs[7].Off();
                    //}

                    GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[statusIndex] = true;

                    //等待气缸抬起
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待气缸抬起", this.Description, 0, ""));
                    while (!GlobalVariable.NozzleAlreadyLiftDown[statusIndex] && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    DoPrecisionCylinder(isFeed: true, isUp: isUp, isClamp: true, isDelay: false, isEnable: false);
                    GlobalVariable.AlreadyGrabProductDown[statusIndex] = true;

                    //等待接收第二次精定位OK的标志
                    startRecvJDW = true;
                    JDWDetailCylinder = String.Empty;
                    while (!SecondJDWOKRecv && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    SecondJDWOKRecv = false;
                    if (!SecondJDWResult)
                    {
                        count--;
                        startRecvJDW = true;
                        GlobalVariable.AlreadyGrabProductDown[statusIndex] = false;
                        GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[statusIndex] = false;
                        if (count >= 0)
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}取精定位失败{JDWDetailCylinder} {count}次!", this.Description, 0, ""));
                        }
                        else
                        {
                            count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                            ShowWarnAndPause($"机械手{_moduleIndex + 1}取精定位失败{JDWDetailCylinder}!", this.Description);
                        }
                        if (!CheckFlowCondition()) return;
                        goto wait2;
                    }

                    //MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待信号复位", this.Description, 0, ""));
                    //while (GlobalVariable.NeedClosePrecisionRecycleProductVacDown[statusIndex] && !IsBreak())
                    //{
                    //    Thread.Sleep(20);
                    //}
                    //if (!CheckFlowCondition()) return;
                    GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[statusIndex] = false;

                    //while (GlobalVariable.NeedOpenPrecisionFeedProductVacDown[statusIndex] && !IsBreak())
                    //{
                    //    Thread.Sleep(20);
                    //}
                    //if (!CheckFlowCondition()) return;
                    GlobalVariable.AlreadyOpenPrecisionFeedProductVacDown[statusIndex] = false;

                    GlobalVariable.AlreadyGrabProductDown[statusIndex] = false;
                    //MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"收到信号复位", this.Description, 0, ""));
                }
            }

            //if (_moduleIndex == 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    if (recycle2.Helper.GetCell(i).Status == CellStatus.HasProduct)
                    {
                        _robotRecycleTray.Helper.SetCellStatus(i, CellStatus.HasProduct);
                        _robotRecycleTray.Helper.SetCellBarcode(i, recycle2.Helper.GetCell(i).SN);
                        _robotRecycleTray.Helper.SetCellResult(i, recycle2.Helper.GetCell(i).Result);

                        recycle2.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        recycle2.Helper.SetCellBarcode(i, string.Empty);
                        recycle2.Helper.SetCellResult(i, TestResult.NoTest);

                        if (i == 0)
                        {
                            _robotTotalTray.Helper.SetCellStatus(2, CellStatus.HasProduct);
                            _robotTotalTray.Helper.SetCellBarcode(2, _robotRecycleTray.Helper.GetCell(i).SN);
                            _robotTotalTray.Helper.SetCellResult(2, _robotRecycleTray.Helper.GetCell(i).Result);
                        }
                        if (i == 1)
                        {
                            _robotTotalTray.Helper.SetCellStatus(6, CellStatus.HasProduct);
                            _robotTotalTray.Helper.SetCellBarcode(6, _robotRecycleTray.Helper.GetCell(i).SN);
                            _robotTotalTray.Helper.SetCellResult(6, _robotRecycleTray.Helper.GetCell(i).Result);
                        }
                    }
                }
                for (int i = 0; i < 2; i++)
                {
                    if (recycle1.Helper.GetCell(i).Status == CellStatus.HasProduct)
                    {
                        _robotRecycleTray.Helper.SetCellStatus(i + 2, CellStatus.HasProduct);
                        _robotRecycleTray.Helper.SetCellBarcode(i + 2, recycle1.Helper.GetCell(i).SN);
                        _robotRecycleTray.Helper.SetCellResult(i + 2, recycle1.Helper.GetCell(i).Result);

                        recycle1.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        recycle1.Helper.SetCellBarcode(i, string.Empty);
                        recycle1.Helper.SetCellResult(i, TestResult.NoTest);

                        if (i == 0)
                        {
                            _robotTotalTray.Helper.SetCellStatus(0, CellStatus.HasProduct);
                            _robotTotalTray.Helper.SetCellBarcode(0, _robotRecycleTray.Helper.GetCell(i).SN);
                            _robotTotalTray.Helper.SetCellResult(0, _robotRecycleTray.Helper.GetCell(i).Result);
                        }
                        if (i == 1)
                        {
                            _robotTotalTray.Helper.SetCellStatus(4, CellStatus.HasProduct);
                            _robotTotalTray.Helper.SetCellBarcode(4, _robotRecycleTray.Helper.GetCell(i).SN);
                            _robotTotalTray.Helper.SetCellResult(4, _robotRecycleTray.Helper.GetCell(i).Result);
                        }
                    }
                }
            }

            //if (_moduleIndex == 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    if (_robotFeedTray.Helper.GetCell(i).Status == CellStatus.HasProduct && feedSts[i] == 1)
                    {
                        feed2.Helper.SetCellStatus(i, CellStatus.HasProduct);
                        feed2.Helper.SetCellBarcode(i, _robotFeedTray.Helper.GetCell(i).SN);
                        feed2.Helper.SetCellResult(i, TestResult.NoTest);

                        _robotFeedTray.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        _robotFeedTray.Helper.SetCellBarcode(i, string.Empty);
                        _robotFeedTray.Helper.SetCellResult(i, TestResult.NoTest);

                        if (i == 0)
                            _robotTotalTray.Helper.SetCellStatus(3, CellStatus.NoProduct);
                        if (i == 1)
                            _robotTotalTray.Helper.SetCellStatus(7, CellStatus.NoProduct);
                    }
                }
                for (int i = 2; i < 4; i++)
                {
                    if (_robotFeedTray.Helper.GetCell(i).Status == CellStatus.HasProduct && feedSts[i] == 1)
                    {
                        feed1.Helper.SetCellStatus(i - 2, CellStatus.HasProduct);
                        feed1.Helper.SetCellBarcode(i - 2, _robotFeedTray.Helper.GetCell(i).SN);
                        feed1.Helper.SetCellResult(i - 2, TestResult.NoTest);

                        _robotFeedTray.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        _robotFeedTray.Helper.SetCellBarcode(i, string.Empty);
                        _robotFeedTray.Helper.SetCellResult(i, TestResult.NoTest);

                        if (i == 2)
                            _robotTotalTray.Helper.SetCellStatus(1, CellStatus.NoProduct);
                        if (i == 3)
                            _robotTotalTray.Helper.SetCellStatus(5, CellStatus.NoProduct);
                    }
                }
            }
        }
        public void GetPutPrecisionInDoubleCylinder(bool isUp, Tray recycle1, Tray recycle2, Tray feed1, Tray feed2)
        {
            List<int> feedSts = _robotFeedTray.Helper.Select(c => c.Status == CellStatus.HasProduct ? 1 : 0).ToList();
            //if (_moduleIndex == 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    if (feed2.Helper.GetCell(i).Status == CellStatus.HasProduct)
                        feedSts[i] = 0;
                }
                for (int i = 0; i < 2; i++)
                {
                    if (feed1.Helper.GetCell(i).Status == CellStatus.HasProduct)
                        feedSts[i + 2] = 0;
                }
            }
            List<int> getSts = new List<int>();
            //if (_moduleIndex == 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    if (recycle2.Helper.GetCell(i).Status == CellStatus.HasProduct)
                        getSts.Add(1);
                    else
                        getSts.Add(0);
                }
                for (int i = 0; i < 2; i++)
                {
                    if (recycle1.Helper.GetCell(i).Status == CellStatus.HasProduct)
                        getSts.Add(1);
                    else
                        getSts.Add(0);
                }
            }
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取放精定位的状态为：{string.Join(",", feedSts)}{string.Join(",", getSts)}", this.Description, 0, ""));
            if (isSimulate)
            {
                Thread.Sleep(1000);
            }
            else
            {
                //机器人去取放料
                string HL = isUp ? "H" : "L";
                TcpClientSend(_robot, new SendPackage() { Message = $"JDW,{HL},{string.Join(",", getSts)},{string.Join(",", feedSts)},\r\n" });
                if (!CheckFlowCondition()) return;
                int count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                Task taskGet = Task.Run(() =>
                {
                #region Get
                waitGet1:
                    JDWGetDetailCylinder = String.Empty;
                    startRecvJDWGet = true;
                    while (!SecondJDWOKRecvGet && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    SecondJDWOKRecvGet = false;
                    if (!SecondJDWResultGet)
                    {
                        startRecvJDWGet = true;
                        count--;
                        if (count >= 0)
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}取精定位失败{JDWGetDetailCylinder} {count}次!", this.Description, 0, ""));
                        }
                        else
                        {
                            count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                            ShowWarnAndPause($"机械手{_moduleIndex + 1}取精定位失败{JDWGetDetailCylinder}!", this.Description);
                        }
                        if (!CheckFlowCondition()) return;
                        goto waitGet1;
                    }
                    int statusIndex = 0;
                    if (_moduleIndex == 0)
                        statusIndex = 0;
                    else if (_moduleIndex == 1)
                        statusIndex = 1;

                    //等待接收第二次精定位OK的标志
                    JDWGetDetailCylinder = String.Empty;
                    startRecvJDWGet = true;
                    if (isUp)
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待机械手告知打开气缸", this.Description, 0, ""));
                        while (!GlobalVariable.NeedClosePrecisionRecycleProductVacUp[statusIndex] && !IsBreak())
                        {
                            Thread.Sleep(20);
                        }
                        if (!CheckFlowCondition()) return;
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待机械手告知打开气缸 完成!", this.Description, 0, ""));
                        DoPrecisionCylinder(isFeed: false, isUp: isUp, isClamp: false);
                        //for (int i = 0; i < getSts.Count; i++)
                        //{
                        //    if (getSts[0] == 1)
                        //        _upVacs[2].Off();
                        //    if (getSts[1] == 1)
                        //        _upVacs[3].Off();
                        //    if (getSts[2] == 1)
                        //        _upVacs[6].Off();
                        //    if (getSts[3] == 1)
                        //        _upVacs[7].Off();
                        //}
                        GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[statusIndex] = true;
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"PC 告知机械手告知已经打开气缸!", this.Description, 0, ""));
                    }
                    else
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待机械手告知打开气缸", this.Description, 0, ""));
                        while (!GlobalVariable.NeedClosePrecisionRecycleProductVacDown[statusIndex] && !IsBreak())
                        {
                            Thread.Sleep(20);
                        }
                        if (!CheckFlowCondition()) return;
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待机械手告知打开气缸 完成!", this.Description, 0, ""));
                        DoPrecisionCylinder(isFeed: false, isUp: isUp, isClamp: false);
                        //for (int i = 0; i < getSts.Count; i++)
                        //{
                        //    if (getSts[0] == 1)
                        //        _downVacs[2].Off();
                        //    if (getSts[1] == 1)
                        //        _downVacs[3].Off();
                        //    if (getSts[2] == 1)
                        //        _downVacs[6].Off();
                        //    if (getSts[3] == 1)
                        //        _downVacs[7].Off();
                        //}
                        GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[statusIndex] = true;
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"PC 告知机械手告知已经打开气缸!", this.Description, 0, ""));
                    }
                    while (!SecondJDWOKRecvGet && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    SecondJDWOKRecvGet = false;
                    if (!SecondJDWResultGet)
                    {
                        startRecvJDWGet = true;
                        if (isUp)
                            GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[statusIndex] = false;
                        else
                            GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[statusIndex] = false;
                        //for (int i = 0; i < getSts.Count; i++)
                        //{
                        //    if (getSts[0] == 1)
                        //        _upVacs[2].On();
                        //    if (getSts[1] == 1)
                        //        _upVacs[3].On();
                        //    if (getSts[2] == 1)
                        //        _upVacs[6].On();
                        //    if (getSts[3] == 1)
                        //        _upVacs[7].On();
                        //}
                        count--;
                        if (count >= 0)
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}取精定位失败{JDWGetDetailCylinder} {count}次!", this.Description, 0, ""));
                        }
                        else
                        {
                            count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                            ShowWarnAndPause($"机械手{_moduleIndex + 1}取精定位失败{JDWGetDetailCylinder}!", this.Description);
                            DoPrecisionCylinder(isFeed: false, isUp: isUp, isClamp: true);
                        }
                        if (!CheckFlowCondition()) return;
                        goto waitGet1;
                    }
                    if (isUp)
                        GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[statusIndex] = false;
                    else
                        GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[statusIndex] = false;
                    #endregion


                });

                Task taskPut = Task.Run(() =>
                {
                #region Put
                waitPut:
                    startRecvJDWPut = true;
                    JDWPutDetailCylinder = String.Empty;
                    while (!SecondJDWOKRecvPut && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    SecondJDWOKRecvPut = false;
                    if (!SecondJDWResultPut)
                    {
                        startRecvJDWPut = true;
                        count--;
                        if (count >= 0)
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}放精定位失败{JDWPutDetailCylinder} {count}次!", this.Description, 0, ""));
                        }
                        else
                        {
                            count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                            ShowWarnAndPause($"机械手{_moduleIndex + 1}放精定位失败{JDWPutDetailCylinder}!", this.Description);
                        }
                        if (!CheckFlowCondition()) return;
                        goto waitPut;
                    }

                    //等待接收第二次精定位OK的标志
                    startRecvJDWPut = true;
                    JDWPutDetailCylinder = String.Empty;
                    int statusIndex = 0;
                    if (_moduleIndex == 0)
                        statusIndex = 0;
                    else if (_moduleIndex == 1)
                        statusIndex = 1;
                    if (isUp)
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待机械手告知关闭气缸", this.Description, 0, ""));
                        while (!GlobalVariable.NeedOpenPrecisionFeedProductVacUp[statusIndex] && !IsBreak())
                        {
                            Thread.Sleep(20);
                        }
                        DoPrecisionCylinder(isFeed: true, isUp: true, isClamp: true);
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待机械手告知关闭气缸 完成", this.Description, 0, ""));
                    }
                    else
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待机械手告知关闭气缸", this.Description, 0, ""));
                        while (!GlobalVariable.NeedOpenPrecisionFeedProductVacDown[statusIndex] && !IsBreak())
                        {
                            Thread.Sleep(20);
                        }
                        DoPrecisionCylinder(isFeed: true, isUp: false, isClamp: true);
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待机械手告知关闭气缸 完成", this.Description, 0, ""));
                    }
                    if (!CheckFlowCondition()) return;
                    //根据有无料开真空
                    //List<bool> vacStatus = feedSts.Select(s => s == 1).ToList();
                    //List<Cylinder> vacs = new List<Cylinder>();
                    //if (isUp)
                    //{
                    //    vacs.Add(_upVacs[0]);
                    //    vacs.Add(_upVacs[1]);
                    //    vacs.Add(_upVacs[4]);
                    //    vacs.Add(_upVacs[5]);
                    //}
                    //else
                    //{
                    //    vacs.Add(_downVacs[0]);
                    //    vacs.Add(_downVacs[1]);
                    //    vacs.Add(_downVacs[4]);
                    //    vacs.Add(_downVacs[5]);
                    //}
                    //MultiCylinderOperate(vacs, 5000, vacStatus);
                    //if (!CheckFlowCondition()) return;
                    if (isUp)
                    {
                        GlobalVariable.AlreadyOpenPrecisionFeedProductVacUp[statusIndex] = true;
                    }
                    else
                    {
                        GlobalVariable.AlreadyOpenPrecisionFeedProductVacDown[statusIndex] = true;
                    }
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"PC 告知机械手告知已经关闭气缸", this.Description, 0, ""));
                    while (!SecondJDWOKRecvPut && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    SecondJDWOKRecvPut = false;
                    if (!SecondJDWResultPut)
                    {
                        startRecvJDWPut = true;
                        if (isUp)
                        {
                            GlobalVariable.AlreadyOpenPrecisionFeedProductVacUp[statusIndex] = false;
                        }
                        else
                        {
                            GlobalVariable.AlreadyOpenPrecisionFeedProductVacDown[statusIndex] = false;
                        }
                        count--;
                        if (count >= 0)
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}放精定位失败{JDWPutDetailCylinder} {count}次!", this.Description, 0, ""));
                        }
                        else
                        {
                            count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                            ShowWarnAndPause($"机械手{_moduleIndex + 1}放精定位失败{JDWPutDetailCylinder}!", this.Description);
                        }
                        if (!CheckFlowCondition()) return;
                        goto waitPut;
                    }
                    if (isUp)
                    {
                        GlobalVariable.AlreadyOpenPrecisionFeedProductVacUp[statusIndex] = false;
                    }
                    else
                    {
                        GlobalVariable.AlreadyOpenPrecisionFeedProductVacDown[statusIndex] = false;
                    }
                    #endregion


                });
                Task.WaitAll(taskGet, taskPut);
            }

            //if (_moduleIndex == 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    if (recycle2.Helper.GetCell(i).Status == CellStatus.HasProduct)
                    {
                        _robotRecycleTray.Helper.SetCellStatus(i, CellStatus.HasProduct);
                        _robotRecycleTray.Helper.SetCellBarcode(i, recycle2.Helper.GetCell(i).SN);
                        _robotRecycleTray.Helper.SetCellResult(i, recycle2.Helper.GetCell(i).Result);

                        recycle2.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        recycle2.Helper.SetCellBarcode(i, string.Empty);
                        recycle2.Helper.SetCellResult(i, TestResult.NoTest);

                        if (i == 0)
                        {
                            _robotTotalTray.Helper.SetCellStatus(2, CellStatus.HasProduct);
                            _robotTotalTray.Helper.SetCellBarcode(2, _robotRecycleTray.Helper.GetCell(i).SN);
                            _robotTotalTray.Helper.SetCellResult(2, _robotRecycleTray.Helper.GetCell(i).Result);
                        }
                        if (i == 1)
                        {
                            _robotTotalTray.Helper.SetCellStatus(6, CellStatus.HasProduct);
                            _robotTotalTray.Helper.SetCellBarcode(6, _robotRecycleTray.Helper.GetCell(i).SN);
                            _robotTotalTray.Helper.SetCellResult(6, _robotRecycleTray.Helper.GetCell(i).Result);
                        }
                    }
                }
                for (int i = 0; i < 2; i++)
                {
                    if (recycle1.Helper.GetCell(i).Status == CellStatus.HasProduct)
                    {
                        _robotRecycleTray.Helper.SetCellStatus(i + 2, CellStatus.HasProduct);
                        _robotRecycleTray.Helper.SetCellBarcode(i + 2, recycle1.Helper.GetCell(i).SN);
                        _robotRecycleTray.Helper.SetCellResult(i + 2, recycle1.Helper.GetCell(i).Result);

                        recycle1.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        recycle1.Helper.SetCellBarcode(i, string.Empty);
                        recycle1.Helper.SetCellResult(i, TestResult.NoTest);

                        if (i == 0)
                        {
                            _robotTotalTray.Helper.SetCellStatus(0, CellStatus.HasProduct);
                            _robotTotalTray.Helper.SetCellBarcode(0, _robotRecycleTray.Helper.GetCell(i).SN);
                            _robotTotalTray.Helper.SetCellResult(0, _robotRecycleTray.Helper.GetCell(i).Result);
                        }
                        if (i == 1)
                        {
                            _robotTotalTray.Helper.SetCellStatus(4, CellStatus.HasProduct);
                            _robotTotalTray.Helper.SetCellBarcode(4, _robotRecycleTray.Helper.GetCell(i).SN);
                            _robotTotalTray.Helper.SetCellResult(4, _robotRecycleTray.Helper.GetCell(i).Result);
                        }
                    }
                }
            }

            //if (_moduleIndex == 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    if (_robotFeedTray.Helper.GetCell(i).Status == CellStatus.HasProduct && feedSts[i] == 1)
                    {
                        feed2.Helper.SetCellStatus(i, CellStatus.HasProduct);
                        feed2.Helper.SetCellBarcode(i, _robotFeedTray.Helper.GetCell(i).SN);
                        feed2.Helper.SetCellResult(i, TestResult.NoTest);

                        _robotFeedTray.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        _robotFeedTray.Helper.SetCellBarcode(i, string.Empty);
                        _robotFeedTray.Helper.SetCellResult(i, TestResult.NoTest);

                        if (i == 0)
                            _robotTotalTray.Helper.SetCellStatus(3, CellStatus.NoProduct);
                        if (i == 1)
                            _robotTotalTray.Helper.SetCellStatus(7, CellStatus.NoProduct);
                    }
                }
                for (int i = 2; i < 4; i++)
                {
                    if (_robotFeedTray.Helper.GetCell(i).Status == CellStatus.HasProduct && feedSts[i] == 1)
                    {
                        feed1.Helper.SetCellStatus(i - 2, CellStatus.HasProduct);
                        feed1.Helper.SetCellBarcode(i - 2, _robotFeedTray.Helper.GetCell(i).SN);
                        feed1.Helper.SetCellResult(i - 2, TestResult.NoTest);

                        _robotFeedTray.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        _robotFeedTray.Helper.SetCellBarcode(i, string.Empty);
                        _robotFeedTray.Helper.SetCellResult(i, TestResult.NoTest);

                        if (i == 2)
                            _robotTotalTray.Helper.SetCellStatus(1, CellStatus.NoProduct);
                        if (i == 3)
                            _robotTotalTray.Helper.SetCellStatus(5, CellStatus.NoProduct);
                    }
                }
            }
        }
        public void GetPrecision(bool isUp, Tray recycle1, Tray recycle2)
        {
            //recycle2对应  robotrecycleTray的 12
            //recycle1对应  robotrecycleTray的 34
            List<int> stsGet = new List<int>();
            //if(_moduleIndex == 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    if (recycle2.Helper.GetCell(i).Status == CellStatus.HasProduct)
                        stsGet.Add(1);
                    else
                        stsGet.Add(0);
                }
                for (int i = 0; i < 2; i++)
                {
                    if (recycle1.Helper.GetCell(i).Status == CellStatus.HasProduct)
                        stsGet.Add(1);
                    else
                        stsGet.Add(0);
                }
            }
            //else
            //{
            //    if (recycle1.Helper.GetCell(1).Status == CellStatus.HasProduct)
            //        stsGet.Add(1);
            //    else
            //        stsGet.Add(0);
            //    if (recycle1.Helper.GetCell(0).Status == CellStatus.HasProduct)
            //        stsGet.Add(1);
            //    else
            //        stsGet.Add(0);
            //    if (recycle2.Helper.GetCell(1).Status == CellStatus.HasProduct)
            //        stsGet.Add(1);
            //    else
            //        stsGet.Add(0);
            //    if (recycle2.Helper.GetCell(0).Status == CellStatus.HasProduct)
            //        stsGet.Add(1);
            //    else
            //        stsGet.Add(0);
            //}
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取放精定位的状态为：{string.Join(",", stsGet)},0,0,0,0", this.Description, 0, ""));
            if (isSimulate)
            {
                Thread.Sleep(1000);
            }
            else
            {
                string HL = isUp ? "H" : "L";
                //机器人去取放料
                //RobotCommandRun($"JDW,{HL},{string.Join(",", stsGet)},0,0,0,0", "机械手取精定位失败!", out string recvStr);
                TcpClientSend(_robot, new SendPackage() { Message = $"JDW,{HL},{string.Join(",", stsGet)},0,0,0,0,\r\n" });
                if (!CheckFlowCondition()) return;
                int count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
            wait1:
                startRecvJDW = true;
                JDWDetailCylinder = String.Empty;
                while (!SecondJDWOKRecv && !IsBreak())
                {
                    Thread.Sleep(20);
                }
                if (!CheckFlowCondition()) return;
                SecondJDWOKRecv = false;
                if (!SecondJDWResult)
                {
                    startRecvJDW = true;
                    count--;
                    if (count >= 0)
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}取精定位失败{JDWDetailCylinder} {count}次!", this.Description, 0, ""));
                    }
                    else
                    {
                        count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                        ShowWarnAndPause($"机械手{_moduleIndex + 1}取精定位失败{JDWDetailCylinder}!", this.Description);
                    }
                    if (!CheckFlowCondition()) return;
                    goto wait1;
                }
                int statusIndex = 0;
                if (_moduleIndex == 0)
                    statusIndex = 0;
                else if (_moduleIndex == 1)
                    statusIndex = 1;

                //等待接收第二次精定位OK的标志
                startRecvJDW = true;
                JDWDetailCylinder = String.Empty;
            wait2:
                if (isUp)
                {
                    while (!GlobalVariable.NeedClosePrecisionRecycleProductVacUp[statusIndex] && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    DoPrecisionCylinder(isFeed: false, isUp: isUp, isClamp: false);
                    //for (int i = 0; i < stsGet.Count; i++)
                    //{
                    //    if (stsGet[0] == 1)
                    //        _upVacs[2].Off();
                    //    if (stsGet[1] == 1)
                    //        _upVacs[3].Off();
                    //    if (stsGet[2] == 1)
                    //        _upVacs[6].Off();
                    //    if (stsGet[3] == 1)
                    //        _upVacs[7].Off();
                    //}
                    GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[statusIndex] = true;
                    //while (GlobalVariable.NeedClosePrecisionRecycleProductVacUp[statusIndex] && !IsBreak())
                    //{
                    //    Thread.Sleep(20);
                    //}
                    //if (!CheckFlowCondition()) return;
                    //GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[statusIndex] = false;
                }
                else
                {
                    while (!GlobalVariable.NeedClosePrecisionRecycleProductVacDown[statusIndex] && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    DoPrecisionCylinder(isFeed: false, isUp: isUp, isClamp: false);
                    //for (int i = 0; i < stsGet.Count; i++)
                    //{
                    //    if (stsGet[0] == 1)
                    //        _downVacs[2].Off();
                    //    if (stsGet[1] == 1)
                    //        _downVacs[3].Off();
                    //    if (stsGet[2] == 1)
                    //        _downVacs[6].Off();
                    //    if (stsGet[3] == 1)
                    //        _downVacs[7].Off();
                    //}
                    GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[statusIndex] = true;
                    //while (GlobalVariable.NeedClosePrecisionRecycleProductVacDown[statusIndex] && !IsBreak())
                    //{
                    //    Thread.Sleep(20);
                    //}
                    //if (!CheckFlowCondition()) return;
                    //GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[statusIndex] = false;
                }
                while (!SecondJDWOKRecv && !IsBreak())
                {
                    Thread.Sleep(20);
                }
                if (!CheckFlowCondition()) return;
                SecondJDWOKRecv = false;
                if (!SecondJDWResult)
                {
                    startRecvJDW = true;
                    if (isUp)
                        GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[statusIndex] = false;
                    else
                        GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[statusIndex] = false;
                    //for (int i = 0; i < stsGet.Count; i++)
                    //{
                    //    if (stsGet[0] == 1)
                    //        _upVacs[2].On();
                    //    if (stsGet[1] == 1)
                    //        _upVacs[3].On();
                    //    if (stsGet[2] == 1)
                    //        _upVacs[6].On();
                    //    if (stsGet[3] == 1)
                    //        _upVacs[7].On();
                    //}
                    count--;
                    if (count >= 0)
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}取精定位失败{JDWDetailCylinder} {count}次!", this.Description, 0, ""));
                    }
                    else
                    {
                        count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                        ShowWarnAndPause($"机械手{_moduleIndex + 1}取精定位失败{JDWDetailCylinder}!", this.Description);
                        DoPrecisionCylinder(isFeed: false, isUp: isUp, isClamp: true);
                    }
                    if (!CheckFlowCondition()) return;
                    goto wait1;
                }
                if (isUp)
                    GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[statusIndex] = false;
                else
                    GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[statusIndex] = false;

            }

            //if (_moduleIndex == 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    if (recycle2.Helper.GetCell(i).Status == CellStatus.HasProduct)
                    {
                        _robotRecycleTray.Helper.SetCellStatus(i, CellStatus.HasProduct);
                        _robotRecycleTray.Helper.SetCellBarcode(i, recycle2.Helper.GetCell(i).SN);
                        _robotRecycleTray.Helper.SetCellResult(i, recycle2.Helper.GetCell(i).Result);

                        if (i == 0)
                        {
                            _robotTotalTray.Helper.SetCellStatus(2, CellStatus.HasProduct);
                            _robotTotalTray.Helper.SetCellBarcode(2, _robotRecycleTray.Helper.GetCell(i).SN);
                            _robotTotalTray.Helper.SetCellResult(2, _robotRecycleTray.Helper.GetCell(i).Result);
                        }
                        if (i == 1)
                        {
                            _robotTotalTray.Helper.SetCellStatus(6, CellStatus.HasProduct);
                            _robotTotalTray.Helper.SetCellBarcode(6, _robotRecycleTray.Helper.GetCell(i).SN);
                            _robotTotalTray.Helper.SetCellResult(6, _robotRecycleTray.Helper.GetCell(i).Result);
                        }

                        recycle2.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        recycle2.Helper.SetCellBarcode(i, string.Empty);
                        recycle2.Helper.SetCellResult(i, TestResult.NoTest);
                    }
                }
                for (int i = 0; i < 2; i++)
                {
                    if (recycle1.Helper.GetCell(i).Status == CellStatus.HasProduct)
                    {
                        _robotRecycleTray.Helper.SetCellStatus(i + 2, CellStatus.HasProduct);
                        _robotRecycleTray.Helper.SetCellBarcode(i + 2, recycle1.Helper.GetCell(i).SN);
                        _robotRecycleTray.Helper.SetCellResult(i + 2, recycle1.Helper.GetCell(i).Result);

                        if (i == 0)
                        {
                            _robotTotalTray.Helper.SetCellStatus(0, CellStatus.HasProduct);
                            _robotTotalTray.Helper.SetCellBarcode(0, _robotRecycleTray.Helper.GetCell(i).SN);
                            _robotTotalTray.Helper.SetCellResult(0, _robotRecycleTray.Helper.GetCell(i).Result);
                        }
                        if (i == 1)
                        {
                            _robotTotalTray.Helper.SetCellStatus(4, CellStatus.HasProduct);
                            _robotTotalTray.Helper.SetCellBarcode(4, _robotRecycleTray.Helper.GetCell(i).SN);
                            _robotTotalTray.Helper.SetCellResult(4, _robotRecycleTray.Helper.GetCell(i).Result);
                        }

                        recycle1.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        recycle1.Helper.SetCellBarcode(i, string.Empty);
                        recycle1.Helper.SetCellResult(i, TestResult.NoTest);
                    }
                }
            }
            //else
            //{
            //    if (recycle1.Helper.GetCell(1).Status == CellStatus.HasProduct)
            //    {
            //        _robotRecycleTray.Helper.SetCellStatus(0, CellStatus.HasProduct);
            //        _robotRecycleTray.Helper.SetCellBarcode(0, recycle1.Helper.GetCell(1).SN);
            //        _robotRecycleTray.Helper.SetCellResult(0, recycle1.Helper.GetCell(1).Result);

            //        _robotTotalTray.Helper.SetCellStatus(2, CellStatus.HasProduct);
            //        _robotTotalTray.Helper.SetCellBarcode(2, _robotRecycleTray.Helper.GetCell(0).SN);
            //        _robotTotalTray.Helper.SetCellResult(2, _robotRecycleTray.Helper.GetCell(0).Result);

            //        recycle1.Helper.SetCellStatus(1, CellStatus.NoProduct);
            //        recycle1.Helper.SetCellBarcode(1, string.Empty);
            //        recycle1.Helper.SetCellResult(1, TestResult.NoTest);
            //    }

            //    if (recycle1.Helper.GetCell(0).Status == CellStatus.HasProduct)
            //    {
            //        _robotRecycleTray.Helper.SetCellStatus(1, CellStatus.HasProduct);
            //        _robotRecycleTray.Helper.SetCellBarcode(1, recycle1.Helper.GetCell(0).SN);
            //        _robotRecycleTray.Helper.SetCellResult(1, recycle1.Helper.GetCell(0).Result);

            //        _robotTotalTray.Helper.SetCellStatus(6, CellStatus.HasProduct);
            //        _robotTotalTray.Helper.SetCellBarcode(6, _robotRecycleTray.Helper.GetCell(1).SN);
            //        _robotTotalTray.Helper.SetCellResult(6, _robotRecycleTray.Helper.GetCell(1).Result);

            //        recycle1.Helper.SetCellStatus(0, CellStatus.NoProduct);
            //        recycle1.Helper.SetCellBarcode(0, string.Empty);
            //        recycle1.Helper.SetCellResult(0, TestResult.NoTest);
            //    }

            //    if (recycle2.Helper.GetCell(1).Status == CellStatus.HasProduct)
            //    {
            //        _robotRecycleTray.Helper.SetCellStatus(2, CellStatus.HasProduct);
            //        _robotRecycleTray.Helper.SetCellBarcode(2, recycle2.Helper.GetCell(1).SN);
            //        _robotRecycleTray.Helper.SetCellResult(2, recycle2.Helper.GetCell(1).Result);

            //        _robotTotalTray.Helper.SetCellStatus(0, CellStatus.HasProduct);
            //        _robotTotalTray.Helper.SetCellBarcode(0, _robotRecycleTray.Helper.GetCell(2).SN);
            //        _robotTotalTray.Helper.SetCellResult(0, _robotRecycleTray.Helper.GetCell(2).Result);

            //        recycle2.Helper.SetCellStatus(1, CellStatus.NoProduct);
            //        recycle2.Helper.SetCellBarcode(1, string.Empty);
            //        recycle2.Helper.SetCellResult(1, TestResult.NoTest);
            //    }

            //    if (recycle2.Helper.GetCell(0).Status == CellStatus.HasProduct)
            //    {
            //        _robotRecycleTray.Helper.SetCellStatus(3, CellStatus.HasProduct);
            //        _robotRecycleTray.Helper.SetCellBarcode(3, recycle2.Helper.GetCell(0).SN);
            //        _robotRecycleTray.Helper.SetCellResult(3, recycle2.Helper.GetCell(0).Result);

            //        _robotTotalTray.Helper.SetCellStatus(4, CellStatus.HasProduct);
            //        _robotTotalTray.Helper.SetCellBarcode(4, _robotRecycleTray.Helper.GetCell(3).SN);
            //        _robotTotalTray.Helper.SetCellResult(4, _robotRecycleTray.Helper.GetCell(3).Result);

            //        recycle2.Helper.SetCellStatus(0, CellStatus.NoProduct);
            //        recycle2.Helper.SetCellBarcode(0, string.Empty);
            //        recycle2.Helper.SetCellResult(0, TestResult.NoTest);
            //    }
            //}
        }
        public void GetPrecisionInDoubleCylinder(bool isUp, Tray recycle1, Tray recycle2)
        {
            //recycle2对应  robotrecycleTray的 12
            //recycle1对应  robotrecycleTray的 34
            List<int> stsGet = new List<int>();
            //if(_moduleIndex == 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    if (recycle2.Helper.GetCell(i).Status == CellStatus.HasProduct)
                        stsGet.Add(1);
                    else
                        stsGet.Add(0);
                }
                for (int i = 0; i < 2; i++)
                {
                    if (recycle1.Helper.GetCell(i).Status == CellStatus.HasProduct)
                        stsGet.Add(1);
                    else
                        stsGet.Add(0);
                }
            }
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取放精定位的状态为：{string.Join(",", stsGet)},0,0,0,0", this.Description, 0, ""));
            if (isSimulate)
            {
                Thread.Sleep(1000);
            }
            else
            {
                string HL = isUp ? "H" : "L";
                //机器人去取放料
                //RobotCommandRun($"JDW,{HL},{string.Join(",", stsGet)},0,0,0,0", "机械手取精定位失败!", out string recvStr);
                TcpClientSend(_robot, new SendPackage() { Message = $"JDW,{HL},{string.Join(",", stsGet)},0,0,0,0,\r\n" });
                if (!CheckFlowCondition()) return;
                int count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
            wait1:
                startRecvJDWGet = true;
                JDWGetDetailCylinder = String.Empty;
                while (!SecondJDWOKRecvGet && !IsBreak())
                {
                    Thread.Sleep(20);
                }
                if (!CheckFlowCondition()) return;
                SecondJDWOKRecvGet = false;
                if (!SecondJDWResultGet)
                {
                    startRecvJDWGet = true;
                    count--;
                    if (count >= 0)
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}取精定位失败{JDWGetDetailCylinder} {count}次!", this.Description, 0, ""));
                    }
                    else
                    {
                        count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                        ShowWarnAndPause($"机械手{_moduleIndex + 1}取精定位失败{JDWGetDetailCylinder}!", this.Description);
                    }
                    if (!CheckFlowCondition()) return;
                    goto wait1;
                }
                int statusIndex = 0;
                if (_moduleIndex == 0)
                    statusIndex = 0;
                else if (_moduleIndex == 1)
                    statusIndex = 1;

                //等待接收第二次精定位OK的标志
                startRecvJDWGet = true;
                JDWGetDetailCylinder = String.Empty;
            wait2:
                if (isUp)
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待机械手告知打开气缸", this.Description, 0, ""));
                    while (!GlobalVariable.NeedClosePrecisionRecycleProductVacUp[statusIndex] && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待机械手告知打开气缸 完成!", this.Description, 0, ""));
                    DoPrecisionCylinder(isFeed: false, isUp: isUp, isClamp: false);
                    //for (int i = 0; i < stsGet.Count; i++)
                    //{
                    //    if (stsGet[0] == 1)
                    //        _upVacs[2].Off();
                    //    if (stsGet[1] == 1)
                    //        _upVacs[3].Off();
                    //    if (stsGet[2] == 1)
                    //        _upVacs[6].Off();
                    //    if (stsGet[3] == 1)
                    //        _upVacs[7].Off();
                    //}
                    GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[statusIndex] = true;
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"PC 告知机械手告知已经打开气缸!", this.Description, 0, ""));
                }
                else
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待机械手告知打开气缸", this.Description, 0, ""));
                    while (!GlobalVariable.NeedClosePrecisionRecycleProductVacDown[statusIndex] && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待机械手告知打开气缸 完成!", this.Description, 0, ""));
                    DoPrecisionCylinder(isFeed: false, isUp: isUp, isClamp: false);
                    //for (int i = 0; i < stsGet.Count; i++)
                    //{
                    //    if (stsGet[0] == 1)
                    //        _downVacs[2].Off();
                    //    if (stsGet[1] == 1)
                    //        _downVacs[3].Off();
                    //    if (stsGet[2] == 1)
                    //        _downVacs[6].Off();
                    //    if (stsGet[3] == 1)
                    //        _downVacs[7].Off();
                    //}
                    GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[statusIndex] = true;
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"PC 告知机械手告知已经打开气缸!", this.Description, 0, ""));
                }
                while (!SecondJDWOKRecvGet && !IsBreak())
                {
                    Thread.Sleep(20);
                }
                if (!CheckFlowCondition()) return;
                SecondJDWOKRecvGet = false;
                if (!SecondJDWResultGet)
                {
                    startRecvJDWGet = true;
                    if (isUp)
                        GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[statusIndex] = false;
                    else
                        GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[statusIndex] = false;
                    //for (int i = 0; i < stsGet.Count; i++)
                    //{
                    //    if (stsGet[0] == 1)
                    //        _upVacs[2].On();
                    //    if (stsGet[1] == 1)
                    //        _upVacs[3].On();
                    //    if (stsGet[2] == 1)
                    //        _upVacs[6].On();
                    //    if (stsGet[3] == 1)
                    //        _upVacs[7].On();
                    //}
                    count--;
                    if (count >= 0)
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}取精定位失败{JDWGetDetailCylinder} {count}次!", this.Description, 0, ""));
                    }
                    else
                    {
                        count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                        ShowWarnAndPause($"机械手{_moduleIndex + 1}取精定位失败{JDWGetDetailCylinder}!", this.Description);
                        DoPrecisionCylinder(isFeed: false, isUp: isUp, isClamp: true);
                    }
                    if (!CheckFlowCondition()) return;
                    goto wait1;
                }
                if (isUp)
                    GlobalVariable.AlreadyClosePrecisionRecycleProductVacUp[statusIndex] = false;
                else
                    GlobalVariable.AlreadyClosePrecisionRecycleProductVacDown[statusIndex] = false;

            }

            //if (_moduleIndex == 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    if (recycle2.Helper.GetCell(i).Status == CellStatus.HasProduct)
                    {
                        _robotRecycleTray.Helper.SetCellStatus(i, CellStatus.HasProduct);
                        _robotRecycleTray.Helper.SetCellBarcode(i, recycle2.Helper.GetCell(i).SN);
                        _robotRecycleTray.Helper.SetCellResult(i, recycle2.Helper.GetCell(i).Result);

                        if (i == 0)
                        {
                            _robotTotalTray.Helper.SetCellStatus(2, CellStatus.HasProduct);
                            _robotTotalTray.Helper.SetCellBarcode(2, _robotRecycleTray.Helper.GetCell(i).SN);
                            _robotTotalTray.Helper.SetCellResult(2, _robotRecycleTray.Helper.GetCell(i).Result);
                        }
                        if (i == 1)
                        {
                            _robotTotalTray.Helper.SetCellStatus(6, CellStatus.HasProduct);
                            _robotTotalTray.Helper.SetCellBarcode(6, _robotRecycleTray.Helper.GetCell(i).SN);
                            _robotTotalTray.Helper.SetCellResult(6, _robotRecycleTray.Helper.GetCell(i).Result);
                        }

                        recycle2.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        recycle2.Helper.SetCellBarcode(i, string.Empty);
                        recycle2.Helper.SetCellResult(i, TestResult.NoTest);
                    }
                }
                for (int i = 0; i < 2; i++)
                {
                    if (recycle1.Helper.GetCell(i).Status == CellStatus.HasProduct)
                    {
                        _robotRecycleTray.Helper.SetCellStatus(i + 2, CellStatus.HasProduct);
                        _robotRecycleTray.Helper.SetCellBarcode(i + 2, recycle1.Helper.GetCell(i).SN);
                        _robotRecycleTray.Helper.SetCellResult(i + 2, recycle1.Helper.GetCell(i).Result);

                        if (i == 0)
                        {
                            _robotTotalTray.Helper.SetCellStatus(0, CellStatus.HasProduct);
                            _robotTotalTray.Helper.SetCellBarcode(0, _robotRecycleTray.Helper.GetCell(i).SN);
                            _robotTotalTray.Helper.SetCellResult(0, _robotRecycleTray.Helper.GetCell(i).Result);
                        }
                        if (i == 1)
                        {
                            _robotTotalTray.Helper.SetCellStatus(4, CellStatus.HasProduct);
                            _robotTotalTray.Helper.SetCellBarcode(4, _robotRecycleTray.Helper.GetCell(i).SN);
                            _robotTotalTray.Helper.SetCellResult(4, _robotRecycleTray.Helper.GetCell(i).Result);
                        }

                        recycle1.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        recycle1.Helper.SetCellBarcode(i, string.Empty);
                        recycle1.Helper.SetCellResult(i, TestResult.NoTest);
                    }
                }
            }

        }
        public void PutPrecision(bool isUp, Tray feed1, Tray feed2)
        {
            //根据robotfeedtray当时手上有的料的状态，来决定放料的有无，下哪几个吸嘴
            List<int> sts = _robotFeedTray.Helper.Select(c => c.Status == CellStatus.HasProduct ? 1 : 0).ToList();
            //再看下当前精定位料的状态，如果feed2有料，也即robotfeedtray的12不用下，如果feed1有料，也即robotfeedtray的34不用下

            //*************静定位  feed1  是左边头， feed2  是右边头
            //对于前模组，精定位feed2的12就是robotfeedtray的12，feed1的12就是robotfeedtray的34
            //if (_moduleIndex == 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    if (feed2.Helper.GetCell(0).Status == CellStatus.HasProduct)
                        sts[0] = 0;
                    if (feed2.Helper.GetCell(1).Status == CellStatus.HasProduct)
                        sts[1] = 0;
                }
                for (int i = 0; i < 2; i++)
                {
                    if (feed1.Helper.GetCell(0).Status == CellStatus.HasProduct)
                        sts[2] = 0;
                    if (feed1.Helper.GetCell(1).Status == CellStatus.HasProduct)
                        sts[3] = 0;
                }
            }
            //对于前模组，精定位feed1的12就是robotfeedtray的21，feed2的12就是robotfeedtray的43
            //else
            //{
            //    for (int i = 0; i < 2; i++)
            //    {
            //        if (feed1.Helper.GetCell(0).Status == CellStatus.HasProduct)
            //            sts[1] = 0;
            //        if (feed1.Helper.GetCell(1).Status == CellStatus.HasProduct)
            //            sts[0] = 0;
            //    }
            //    for (int i = 0; i < 2; i++)
            //    {
            //        if (feed2.Helper.GetCell(0).Status == CellStatus.HasProduct)
            //            sts[3] = 0;
            //        if (feed2.Helper.GetCell(1).Status == CellStatus.HasProduct)
            //            sts[2] = 0;
            //    }
            //}

            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取放精定位的状态为：{"0,0,0,0"}{string.Join(",", sts)}", this.Description, 0, ""));
            if (isSimulate)
            {
                Thread.Sleep(1000);
            }
            else
            {
                string HL = isUp ? "H" : "L";
                //机器人去取料
                //RobotCommandRun($"JDW,{HL},{"0,0,0,0"},{string.Join(",", sts)}", "机械手取精定位失败!", out string recvStr);
                TcpClientSend(_robot, new SendPackage() { Message = $"JDW,{HL},{"0,0,0,0"},{string.Join(",", sts)},\r\n" });
                if (!CheckFlowCondition()) return;
                int count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
            wait:
                startRecvJDW = true;
                JDWDetailCylinder = string.Empty;
                while (!SecondJDWOKRecv && !IsBreak())
                {
                    Thread.Sleep(20);
                }
                if (!CheckFlowCondition()) return;
                SecondJDWOKRecv = false;
                if (!SecondJDWResult)
                {
                    startRecvJDW = true;
                    count--;
                    if (count >= 0)
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}放精定位失败{JDWDetailCylinder} {count}次!", this.Description, 0, ""));
                    }
                    else
                    {
                        count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                        ShowWarnAndPause($"机械手{_moduleIndex + 1}放精定位失败{JDWDetailCylinder}!", this.Description);
                    }
                    if (!CheckFlowCondition()) return;
                    goto wait;
                }

                //等待接收第二次精定位OK的标志
                startRecvJDW = true;
                JDWDetailCylinder = string.Empty;
                int statusIndex = 0;
                if (_moduleIndex == 0)
                    statusIndex = 0;
                else if (_moduleIndex == 1)
                    statusIndex = 1;
                if (isUp)
                {
                    while (!GlobalVariable.NeedOpenPrecisionFeedProductVacUp[statusIndex] && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    DoPrecisionCylinder(isFeed: true, isUp: isUp, isClamp: true);
                }
                else
                {
                    while (!GlobalVariable.NeedOpenPrecisionFeedProductVacDown[statusIndex] && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    DoPrecisionCylinder(isFeed: true, isUp: isUp, isClamp: true);
                }
                if (!CheckFlowCondition()) return;
                //根据有无料开真空
                //List<bool> vacStatus = sts.Select(s => s == 1).ToList();
                //List<Cylinder> vacs = new List<Cylinder>();
                //if (isUp)
                //{
                //    vacs.Add(_upVacs[0]);
                //    vacs.Add(_upVacs[1]);
                //    vacs.Add(_upVacs[4]);
                //    vacs.Add(_upVacs[5]);
                //}
                //else
                //{
                //    vacs.Add(_downVacs[0]);
                //    vacs.Add(_downVacs[1]);
                //    vacs.Add(_downVacs[4]);
                //    vacs.Add(_downVacs[5]);
                //}
                //MultiCylinderOperate(vacs, 5000, vacStatus);
                if (!CheckFlowCondition()) return;

                if (isUp)
                {
                    GlobalVariable.AlreadyOpenPrecisionFeedProductVacUp[statusIndex] = true;
                }
                else
                {
                    GlobalVariable.AlreadyOpenPrecisionFeedProductVacDown[statusIndex] = true;
                }
                while (!SecondJDWOKRecv && !IsBreak())
                {
                    Thread.Sleep(20);
                }
                if (!CheckFlowCondition()) return;
                SecondJDWOKRecv = false;
                if (!SecondJDWResult)
                {
                    startRecvJDW = true;
                    if (isUp)
                    {
                        GlobalVariable.AlreadyOpenPrecisionFeedProductVacUp[statusIndex] = false;
                    }
                    else
                    {
                        GlobalVariable.AlreadyOpenPrecisionFeedProductVacDown[statusIndex] = false;
                    }
                    count--;
                    if (count >= 0)
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}放精定位失败{JDWDetailCylinder} {count}次!", this.Description, 0, ""));
                    }
                    else
                    {
                        count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                        ShowWarnAndPause($"机械手{_moduleIndex + 1}放精定位失败{JDWDetailCylinder}!", this.Description);
                    }
                    if (!CheckFlowCondition()) return;
                    goto wait;
                }
                if (isUp)
                {
                    GlobalVariable.AlreadyOpenPrecisionFeedProductVacUp[statusIndex] = false;
                }
                else
                {
                    GlobalVariable.AlreadyOpenPrecisionFeedProductVacDown[statusIndex] = false;
                }
            }

            //if (_moduleIndex == 0)
            {
                //交换料状态
                //robotfeedtray的12给的是精定位12，也即feed2，给右侧arm
                for (int i = 0; i < 2; i++)
                {
                    //手上有料且精定位没料
                    if (_robotFeedTray.Helper.GetCell(i).Status == CellStatus.HasProduct && sts[i] == 1)
                    {
                        feed2.Helper.SetCellStatus(i, CellStatus.HasProduct);
                        feed2.Helper.SetCellBarcode(i, _robotFeedTray.Helper.GetCell(i).SN);
                        feed2.Helper.SetCellResult(i, TestResult.NoTest);

                        _robotFeedTray.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        _robotFeedTray.Helper.SetCellBarcode(i, string.Empty);
                        _robotFeedTray.Helper.SetCellResult(i, TestResult.NoTest);

                        if (i == 0)
                        {
                            _robotTotalTray.Helper.SetCellStatus(3, CellStatus.NoProduct);
                            _robotTotalTray.Helper.SetCellBarcode(3, string.Empty);
                            _robotTotalTray.Helper.SetCellResult(3, TestResult.NoTest);
                        }
                        if (i == 1)
                        {
                            _robotTotalTray.Helper.SetCellStatus(7, CellStatus.NoProduct);
                            _robotTotalTray.Helper.SetCellBarcode(7, string.Empty);
                            _robotTotalTray.Helper.SetCellResult(7, TestResult.NoTest);
                        }
                    }
                }
                for (int i = 2; i < 4; i++)
                {
                    if (_robotFeedTray.Helper.GetCell(i).Status == CellStatus.HasProduct && sts[i] == 1)
                    {
                        feed1.Helper.SetCellStatus(i - 2, CellStatus.HasProduct);
                        feed1.Helper.SetCellBarcode(i - 2, _robotFeedTray.Helper.GetCell(i).SN);
                        feed1.Helper.SetCellResult(i - 2, TestResult.NoTest);

                        _robotFeedTray.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        _robotFeedTray.Helper.SetCellBarcode(i, string.Empty);
                        _robotFeedTray.Helper.SetCellResult(i, TestResult.NoTest);

                        if (i == 2)
                        {
                            _robotTotalTray.Helper.SetCellStatus(1, CellStatus.NoProduct);
                            _robotTotalTray.Helper.SetCellBarcode(1, string.Empty);
                            _robotTotalTray.Helper.SetCellResult(1, TestResult.NoTest);
                        }
                        if (i == 3)
                        {
                            _robotTotalTray.Helper.SetCellStatus(5, CellStatus.NoProduct);
                            _robotTotalTray.Helper.SetCellBarcode(5, string.Empty);
                            _robotTotalTray.Helper.SetCellResult(5, TestResult.NoTest);
                        }
                    }
                }
            }
            //else
            //{
            //    //交换料状态
            //    //robotfeedtray的12给的是精定位12，也即feed2，给右侧arm
            //    for (int i = 0; i < 2; i++)
            //    {
            //        if (i == 0)
            //        {
            //            if (_robotFeedTray.Helper.GetCell(0).Status == CellStatus.HasProduct && sts[0] == 1)
            //            {
            //                feed1.Helper.SetCellStatus(1, CellStatus.HasProduct);
            //                feed1.Helper.SetCellBarcode(1, _robotFeedTray.Helper.GetCell(0).SN);
            //                feed1.Helper.SetCellResult(1, TestResult.NoTest);

            //                _robotFeedTray.Helper.SetCellStatus(0, CellStatus.NoProduct);
            //                _robotFeedTray.Helper.SetCellBarcode(0, string.Empty);
            //                _robotFeedTray.Helper.SetCellResult(0, TestResult.NoTest);
            //            }
            //        }
            //        else
            //        {
            //            if (_robotFeedTray.Helper.GetCell(1).Status == CellStatus.HasProduct && sts[1] == 1)
            //            {
            //                feed1.Helper.SetCellStatus(0, CellStatus.HasProduct);
            //                feed1.Helper.SetCellBarcode(0, _robotFeedTray.Helper.GetCell(1).SN);
            //                feed1.Helper.SetCellResult(0, TestResult.NoTest);

            //                _robotFeedTray.Helper.SetCellStatus(1, CellStatus.NoProduct);
            //                _robotFeedTray.Helper.SetCellBarcode(1, string.Empty);
            //                _robotFeedTray.Helper.SetCellResult(1, TestResult.NoTest);
            //            }
            //        }
            //        if (i == 0)
            //        {
            //            _robotTotalTray.Helper.SetCellStatus(3, CellStatus.NoProduct);
            //            _robotTotalTray.Helper.SetCellBarcode(3, string.Empty);
            //            _robotTotalTray.Helper.SetCellResult(3, TestResult.NoTest);
            //        }
            //        if (i == 1)
            //        {
            //            _robotTotalTray.Helper.SetCellStatus(7, CellStatus.NoProduct);
            //            _robotTotalTray.Helper.SetCellBarcode(7, string.Empty);
            //            _robotTotalTray.Helper.SetCellResult(7, TestResult.NoTest);
            //        }
            //    }
            //    for (int i = 2; i < 4; i++)
            //    {
            //        if (i == 2)
            //        {
            //            if (_robotFeedTray.Helper.GetCell(2).Status == CellStatus.HasProduct && sts[2] == 1)
            //            {
            //                feed2.Helper.SetCellStatus(1, CellStatus.HasProduct);
            //                feed2.Helper.SetCellBarcode(1, _robotFeedTray.Helper.GetCell(2).SN);
            //                feed2.Helper.SetCellResult(1, TestResult.NoTest);

            //                _robotFeedTray.Helper.SetCellStatus(2, CellStatus.NoProduct);
            //                _robotFeedTray.Helper.SetCellBarcode(2, string.Empty);
            //                _robotFeedTray.Helper.SetCellResult(2, TestResult.NoTest);
            //            }
            //        }
            //        else
            //        {
            //            if (_robotFeedTray.Helper.GetCell(3).Status == CellStatus.HasProduct && sts[3] == 1)
            //            {
            //                feed2.Helper.SetCellStatus(0, CellStatus.HasProduct);
            //                feed2.Helper.SetCellBarcode(0, _robotFeedTray.Helper.GetCell(3).SN);
            //                feed2.Helper.SetCellResult(0, TestResult.NoTest);

            //                _robotFeedTray.Helper.SetCellStatus(3, CellStatus.NoProduct);
            //                _robotFeedTray.Helper.SetCellBarcode(3, string.Empty);
            //                _robotFeedTray.Helper.SetCellResult(3, TestResult.NoTest);
            //            }
            //        }
            //        if (i == 2)
            //        {
            //            _robotTotalTray.Helper.SetCellStatus(1, CellStatus.NoProduct);
            //            _robotTotalTray.Helper.SetCellBarcode(1, string.Empty);
            //            _robotTotalTray.Helper.SetCellResult(1, TestResult.NoTest);
            //        }
            //        if (i == 3)
            //        {
            //            _robotTotalTray.Helper.SetCellStatus(5, CellStatus.NoProduct);
            //            _robotTotalTray.Helper.SetCellBarcode(5, string.Empty);
            //            _robotTotalTray.Helper.SetCellResult(5, TestResult.NoTest);
            //        }
            //    }
            //}
        }
        public void PutPrecisionInDoubleCylinder(bool isUp, Tray feed1, Tray feed2)
        {
            //根据robotfeedtray当时手上有的料的状态，来决定放料的有无，下哪几个吸嘴
            List<int> sts = _robotFeedTray.Helper.Select(c => c.Status == CellStatus.HasProduct ? 1 : 0).ToList();
            //再看下当前精定位料的状态，如果feed2有料，也即robotfeedtray的12不用下，如果feed1有料，也即robotfeedtray的34不用下

            //*************静定位  feed1  是左边头， feed2  是右边头
            //对于前模组，精定位feed2的12就是robotfeedtray的12，feed1的12就是robotfeedtray的34
            //if (_moduleIndex == 0)
            {
                for (int i = 0; i < 2; i++)
                {
                    if (feed2.Helper.GetCell(0).Status == CellStatus.HasProduct)
                        sts[0] = 0;
                    if (feed2.Helper.GetCell(1).Status == CellStatus.HasProduct)
                        sts[1] = 0;
                }
                for (int i = 0; i < 2; i++)
                {
                    if (feed1.Helper.GetCell(0).Status == CellStatus.HasProduct)
                        sts[2] = 0;
                    if (feed1.Helper.GetCell(1).Status == CellStatus.HasProduct)
                        sts[3] = 0;
                }
            }

            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"取放精定位的状态为：{"0,0,0,0"}{string.Join(",", sts)}", this.Description, 0, ""));
            if (isSimulate)
            {
                Thread.Sleep(1000);
            }
            else
            {
                string HL = isUp ? "H" : "L";
                //机器人去取料
                //RobotCommandRun($"JDW,{HL},{"0,0,0,0"},{string.Join(",", sts)}", "机械手取精定位失败!", out string recvStr);
                TcpClientSend(_robot, new SendPackage() { Message = $"JDW,{HL},{"0,0,0,0"},{string.Join(",", sts)},\r\n" });
                if (!CheckFlowCondition()) return;
                int count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
            wait:
                startRecvJDWPut = true;
                JDWPutDetailCylinder = string.Empty;
                while (!SecondJDWOKRecvPut && !IsBreak())
                {
                    Thread.Sleep(20);
                }
                if (!CheckFlowCondition()) return;
                SecondJDWOKRecvPut = false;
                if (!SecondJDWResultPut)
                {
                    startRecvJDWPut = true;
                    count--;
                    if (count >= 0)
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}放精定位失败{JDWPutDetailCylinder} {count}次!", this.Description, 0, ""));
                    }
                    else
                    {
                        count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                        ShowWarnAndPause($"机械手{_moduleIndex + 1}放精定位失败{JDWPutDetailCylinder}!", this.Description);
                    }
                    if (!CheckFlowCondition()) return;
                    goto wait;
                }

                //等待接收第二次精定位OK的标志
                startRecvJDWPut = true;
                JDWPutDetailCylinder = string.Empty;
                int statusIndex = 0;
                if (_moduleIndex == 0)
                    statusIndex = 0;
                else if (_moduleIndex == 1)
                    statusIndex = 1;
                if (isUp)
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待机械手告知关闭气缸", this.Description, 0, ""));
                    while (!GlobalVariable.NeedOpenPrecisionFeedProductVacUp[statusIndex] && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待机械手告知关闭气缸 完成", this.Description, 0, ""));
                    DoPrecisionCylinder(isFeed: true, isUp: true, isClamp: true);
                }
                else
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待机械手告知关闭气缸", this.Description, 0, ""));
                    while (!GlobalVariable.NeedOpenPrecisionFeedProductVacDown[statusIndex] && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待机械手告知关闭气缸 完成", this.Description, 0, ""));
                    DoPrecisionCylinder(isFeed: true, isUp: false, isClamp: true);
                }
                if (!CheckFlowCondition()) return;
                //根据有无料开真空
                //List<bool> vacStatus = sts.Select(s => s == 1).ToList();
                //List<Cylinder> vacs = new List<Cylinder>();
                //if (isUp)
                //{
                //    vacs.Add(_upVacs[0]);
                //    vacs.Add(_upVacs[1]);
                //    vacs.Add(_upVacs[4]);
                //    vacs.Add(_upVacs[5]);
                //}
                //else
                //{
                //    vacs.Add(_downVacs[0]);
                //    vacs.Add(_downVacs[1]);
                //    vacs.Add(_downVacs[4]);
                //    vacs.Add(_downVacs[5]);
                //}
                //MultiCylinderOperate(vacs, 5000, vacStatus);
                //if (!CheckFlowCondition()) return;

                if (isUp)
                {
                    GlobalVariable.AlreadyOpenPrecisionFeedProductVacUp[statusIndex] = true;
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"PC 告知机械手告知已经关闭气缸", this.Description, 0, ""));
                }
                else
                {
                    GlobalVariable.AlreadyOpenPrecisionFeedProductVacDown[statusIndex] = true;
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"PC 告知机械手告知已经关闭气缸", this.Description, 0, ""));
                }
                while (!SecondJDWOKRecvPut && !IsBreak())
                {
                    Thread.Sleep(20);
                }
                if (!CheckFlowCondition()) return;
                SecondJDWOKRecvPut = false;
                if (!SecondJDWResultPut)
                {
                    startRecvJDWPut = true;
                    if (isUp)
                    {
                        GlobalVariable.AlreadyOpenPrecisionFeedProductVacUp[statusIndex] = false;
                    }
                    else
                    {
                        GlobalVariable.AlreadyOpenPrecisionFeedProductVacDown[statusIndex] = false;
                    }
                    count--;
                    if (count >= 0)
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleIndex + 1}放精定位失败{JDWPutDetailCylinder} {count}次!", this.Description, 0, ""));
                    }
                    else
                    {
                        count = SystemConfig.Instance.TestParam.RobotGetPWarnTime;
                        ShowWarnAndPause($"机械手{_moduleIndex + 1}放精定位失败{JDWPutDetailCylinder}!", this.Description);
                    }
                    if (!CheckFlowCondition()) return;
                    goto wait;
                }
                if (isUp)
                {
                    GlobalVariable.AlreadyOpenPrecisionFeedProductVacUp[statusIndex] = false;
                }
                else
                {
                    GlobalVariable.AlreadyOpenPrecisionFeedProductVacDown[statusIndex] = false;
                }
            }

            //if (_moduleIndex == 0)
            {
                //交换料状态
                //robotfeedtray的12给的是精定位12，也即feed2，给右侧arm
                for (int i = 0; i < 2; i++)
                {
                    //手上有料且精定位没料
                    if (_robotFeedTray.Helper.GetCell(i).Status == CellStatus.HasProduct && sts[i] == 1)
                    {
                        feed2.Helper.SetCellStatus(i, CellStatus.HasProduct);
                        feed2.Helper.SetCellBarcode(i, _robotFeedTray.Helper.GetCell(i).SN);
                        feed2.Helper.SetCellResult(i, TestResult.NoTest);

                        _robotFeedTray.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        _robotFeedTray.Helper.SetCellBarcode(i, string.Empty);
                        _robotFeedTray.Helper.SetCellResult(i, TestResult.NoTest);

                        if (i == 0)
                        {
                            _robotTotalTray.Helper.SetCellStatus(3, CellStatus.NoProduct);
                            _robotTotalTray.Helper.SetCellBarcode(3, string.Empty);
                            _robotTotalTray.Helper.SetCellResult(3, TestResult.NoTest);
                        }
                        if (i == 1)
                        {
                            _robotTotalTray.Helper.SetCellStatus(7, CellStatus.NoProduct);
                            _robotTotalTray.Helper.SetCellBarcode(7, string.Empty);
                            _robotTotalTray.Helper.SetCellResult(7, TestResult.NoTest);
                        }
                    }
                }
                for (int i = 2; i < 4; i++)
                {
                    if (_robotFeedTray.Helper.GetCell(i).Status == CellStatus.HasProduct && sts[i] == 1)
                    {
                        feed1.Helper.SetCellStatus(i - 2, CellStatus.HasProduct);
                        feed1.Helper.SetCellBarcode(i - 2, _robotFeedTray.Helper.GetCell(i).SN);
                        feed1.Helper.SetCellResult(i - 2, TestResult.NoTest);

                        _robotFeedTray.Helper.SetCellStatus(i, CellStatus.NoProduct);
                        _robotFeedTray.Helper.SetCellBarcode(i, string.Empty);
                        _robotFeedTray.Helper.SetCellResult(i, TestResult.NoTest);

                        if (i == 2)
                        {
                            _robotTotalTray.Helper.SetCellStatus(1, CellStatus.NoProduct);
                            _robotTotalTray.Helper.SetCellBarcode(1, string.Empty);
                            _robotTotalTray.Helper.SetCellResult(1, TestResult.NoTest);
                        }
                        if (i == 3)
                        {
                            _robotTotalTray.Helper.SetCellStatus(5, CellStatus.NoProduct);
                            _robotTotalTray.Helper.SetCellBarcode(5, string.Empty);
                            _robotTotalTray.Helper.SetCellResult(5, TestResult.NoTest);
                        }
                    }
                }
            }
        }

        public CommunicationHelper GetRobot()
        {
            return _robot;
        }
        public void safetyCheck(bool upReady)
        {
            if (!isSimulate)
            {
                if (!upReady)
                {
                    while (_upInMove.WaitOn())
                    {
                        ShowWarnAndPause("精定位上层不在安全位置", $"Robot{_moduleIndex + 1}模组");
                        Thread.Sleep(20);
                    }
                    while (!_upInOrigin.WaitOn())
                    {
                        ShowWarnAndPause("精定位上层不在安全位置", $"Robot{_moduleIndex + 1}模组");
                        Thread.Sleep(20);
                    }
                }
            }
        }
        List<RobotPoint> boat1Positions;
        List<RobotPoint> boat2Positions;
        List<RobotPoint> boat1TransPositions;
        List<RobotPoint> boat2TransPositions;
        public bool CaptureOKTray(int robotIndex)
        {
            if (isSimulate)
                Thread.Sleep(500);
            else
            {
                DateTime now = DateTime.Now;
                //机器人去取料
                RobotCommandRun($"CaptureTray,1", $"机械手{robotIndex + 1}去下料拍照点位1失败!", out string recvStr1);
                TimeSpan ts = DateTime.Now - now;
                LogHelper.Instance.Log(this.Description, $"机械手去下料拍照点位1:{ts.Milliseconds}", MessageLevel.CT);
                if (!CheckFlowCondition()) return false;

                //if (!GlobalVariable.IsDryRun)
                {
                    while (!isAllPointsGot && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    isAllPointsGot = false;
                    ExtractPointsFromString2(pointStr);
                    pointStr = "";
                }

                now = DateTime.Now;
                if (!VisionCaptureBoat(0, robotIndex + 1))
                {
                    ts = DateTime.Now - now;
                    LogHelper.Instance.Log(this.Description, $"下料拍照1时间:{ts.Milliseconds}", MessageLevel.CT);
                    return false;
                }
                ts = DateTime.Now - now;
                LogHelper.Instance.Log(this.Description, $"下料拍照1时间:{ts.Milliseconds}", MessageLevel.CT);
                if (!CheckFlowCondition()) return false;
            }

            if (isSimulate)
                Thread.Sleep(500);
            else
            {
                DateTime now = DateTime.Now;
                RobotCommandRun($"CaptureTray,2", $"机械手{robotIndex + 1}去下料拍照点位2失败!", out string recvStr2);
                TimeSpan ts = DateTime.Now - now;
                LogHelper.Instance.Log(this.Description, $"机械手去下料拍照点位2:{ts.Milliseconds}", MessageLevel.CT);
                if (!CheckFlowCondition()) return false;

                while (!isAllPointsGot && !IsBreak())
                {
                    Thread.Sleep(20);
                }
                isAllPointsGot = false;
                ExtractPointsFromString(pointStr);
                pointStr = "";

                now = DateTime.Now;
                if (!VisionCaptureBoat(1, robotIndex + 1))
                {
                    ts = DateTime.Now - now;
                    LogHelper.Instance.Log(this.Description, $"下料拍照2时间:{ts.Milliseconds}", MessageLevel.CT);
                    return false;
                }
                ts = DateTime.Now - now;
                LogHelper.Instance.Log(this.Description, $"下料拍照2时间:{ts.Milliseconds}", MessageLevel.CT);
            }

            if (!CheckFlowCondition()) return false;
            return true;
        }
        List<RobotPoint> feedPositions;
        List<RobotPoint> feedTransPositions;
        public void CaptureFeedTray()
        {
            if (isSimulate)
                Thread.Sleep(500);
            else
            {
                DateTime now = DateTime.Now;
                //机器人去取料
                RobotCommandRun($"CaptureFeed,1", "机械手去上料拍照点位1失败!", out string recvStr1);
                TimeSpan ts = DateTime.Now - now;
                LogHelper.Instance.Log(this.Description, $"机械手去上料拍照点位1:{ts.Milliseconds}", MessageLevel.CT);
                if (!CheckFlowCondition()) return;

                //if (!GlobalVariable.IsDryRun)
                {
                    while (!isAllPointsGot && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                    isAllPointsGot = false;
                    ExtractPointsFromString3(pointStr);
                    pointStr = "";
                }

                now = DateTime.Now;
                VisionCaptureTray(0);
                ts = DateTime.Now - now;
                LogHelper.Instance.Log(this.Description, $"上料拍照1时间:{ts.Milliseconds}", MessageLevel.CT);
                if (!CheckFlowCondition()) return;
            }

            if (isSimulate)
                Thread.Sleep(500);
            else
            {
                DateTime now = DateTime.Now;
                RobotCommandRun($"CaptureFeed,2", "机械手去上料拍照点位2失败!", out string recvStr2);
                TimeSpan ts = DateTime.Now - now;
                LogHelper.Instance.Log(this.Description, $"机械手去上料拍照点位2:{ts.Milliseconds}", MessageLevel.CT);
                if (!CheckFlowCondition()) return;

                while (!isAllPointsGot && !IsBreak())
                {
                    Thread.Sleep(20);
                }
                if (!CheckFlowCondition()) return;
                isAllPointsGot = false;
                ExtractPointsFromString4(pointStr);
                pointStr = "";

                now = DateTime.Now;
                VisionCaptureTray(1);
                ts = DateTime.Now - now;
                LogHelper.Instance.Log(this.Description, $"上料拍照2时间:{ts.Milliseconds}", MessageLevel.CT);
            }

            if (!CheckFlowCondition()) return;
        }
        RobotPoint capturePosition1;
        RobotPoint capturePosition2;
        public void ExtractPointsFromString2(string pointStr)
        {
            string[] strs = pointStr.Split(new char[2] { '\r', '\n' });
            List<RobotPoint> allPoints = new List<RobotPoint>();
            for (int i = 0; i < strs.Length; i++)
            {
                if (strs[i].Contains("P"))
                {
                    string raw = strs[i].Substring(strs[i].IndexOf('=') + 1);
                    string[] praw = raw.Split(' ');
                    RobotPoint rb = new RobotPoint(Convert.ToDouble(praw[0]),
                                                   Convert.ToDouble(praw[1]),
                                                   Convert.ToDouble(praw[3]));
                    allPoints.Add(rb);
                }
            }
            capturePosition1 = allPoints[0];
            capturePosition2 = allPoints[1];
        }
        RobotPoint capturePositionFeed1;
        RobotPoint capturePositionFeed2;
        public void ExtractPointsFromString3(string pointStr)
        {
            string[] strs = pointStr.Split(new char[2] { '\r', '\n' });
            List<RobotPoint> allPoints = new List<RobotPoint>();
            for (int i = 0; i < strs.Length; i++)
            {
                if (strs[i].Contains("P"))
                {
                    string raw = strs[i].Substring(strs[i].IndexOf('=') + 1);
                    string[] praw = raw.Split(' ');
                    RobotPoint rb = new RobotPoint(Convert.ToDouble(praw[0]),
                                                   Convert.ToDouble(praw[1]),
                                                   Convert.ToDouble(praw[3]));
                    allPoints.Add(rb);
                }
            }
            capturePositionFeed1 = allPoints[0];
            capturePositionFeed2 = allPoints[1];
        }
        public void ExtractPointsFromString(string pointStr)
        {
            string[] strs = pointStr.Split(new char[2] { '\r', '\n' });
            List<RobotPoint> allPoints = new List<RobotPoint>();
            for (int i = 0; i < strs.Length; i++)
            {
                if (strs[i].Contains("P"))
                {
                    string raw = strs[i].Substring(strs[i].IndexOf('=') + 1);
                    string[] praw = raw.Split(' ');
                    RobotPoint rb = new RobotPoint(Convert.ToDouble(praw[0]),
                                                   Convert.ToDouble(praw[1]),
                                                   Convert.ToDouble(praw[3]));
                    allPoints.Add(rb);
                }
            }
            boat1Positions = allPoints.Take(15).ToList();
            boat2Positions = allPoints.Skip(15).Take(15).ToList();
        }
        public void ExtractPointsFromString4(string pointStr)
        {
            string[] strs = pointStr.Split(new char[2] { '\r', '\n' });
            feedPositions = new List<RobotPoint>();
            for (int i = 0; i < strs.Length; i++)
            {
                if (strs[i].Contains("P"))
                {
                    string raw = strs[i].Substring(strs[i].IndexOf('=') + 1);
                    string[] praw = raw.Split(' ');
                    RobotPoint rb = new RobotPoint(Convert.ToDouble(praw[0]),
                                                   Convert.ToDouble(praw[1]),
                                                   Convert.ToDouble(praw[3]));
                    feedPositions.Add(rb);
                }
            }
        }
        PointF boatp1;
        PointF boatp2;
        PointF boatc1;
        PointF boatc2;
        public bool VisionCaptureBoat(int captureIndex, int robotIndex)
        {
            if ((GlobalVariable.IsDryRun || SystemConfig.Instance.UsingStatus.IsVisionSimulate
             || (robotIndex == 1 && !SystemConfig.Instance.UsingStatus.RecycleTrayCompensationEnable)
             || (robotIndex == 2 && !SystemConfig.Instance.UsingStatus.RecycleTrayCompensationEnableRobot2)) && captureIndex == 1)
            {
                boat1TransPositions = new List<RobotPoint>();
                boat2TransPositions = new List<RobotPoint>();
                for (int i = 0; i < boat1Positions.Count; i++)
                {
                    RobotPoint newpoint = new RobotPoint();
                    if (robotIndex == 1)
                    {
                        newpoint.X = boat1Positions[i].X + SystemConfig.Instance.UsingStatus.RecycleTrayCompensationX;
                        newpoint.Y = boat1Positions[i].Y + SystemConfig.Instance.UsingStatus.RecycleTrayCompensationY;
                        newpoint.R = boat1Positions[i].R;
                    }
                    else
                    {
                        newpoint.X = boat1Positions[i].X + SystemConfig.Instance.UsingStatus.RecycleTrayCompensationXRobot2;
                        newpoint.Y = boat1Positions[i].Y + SystemConfig.Instance.UsingStatus.RecycleTrayCompensationYRobot2;
                        newpoint.R = boat1Positions[i].R;
                    }
                    boat1TransPositions.Add(newpoint);
                }
                for (int i = 0; i < boat2Positions.Count; i++)
                {
                    RobotPoint newpoint = new RobotPoint();
                    if (robotIndex == 1)
                    {
                        newpoint.X = boat2Positions[i].X + SystemConfig.Instance.UsingStatus.RecycleTrayCompensationX;
                        newpoint.Y = boat2Positions[i].Y + SystemConfig.Instance.UsingStatus.RecycleTrayCompensationY;
                        newpoint.R = boat2Positions[i].R;
                    }
                    else
                    {
                        newpoint.X = boat2Positions[i].X + SystemConfig.Instance.UsingStatus.RecycleTrayCompensationXRobot2;
                        newpoint.Y = boat2Positions[i].Y + SystemConfig.Instance.UsingStatus.RecycleTrayCompensationYRobot2;
                        newpoint.R = boat2Positions[i].R;
                    }
                    boat2TransPositions.Add(newpoint);
                }
                Thread.Sleep(500);
                return true;
            }

            if ((robotIndex == 1 && !SystemConfig.Instance.UsingStatus.RecycleTrayCompensationEnable)
             || (robotIndex == 2 && !SystemConfig.Instance.UsingStatus.RecycleTrayCompensationEnableRobot2))
            {
                return true;
            }

            if (!GlobalVariable.IsDryRun)
            {
                try
                {
                    #region 视觉
                    SendPackage sp = new SendPackage();
                    if (captureIndex == 0)
                        sp.Message = $"CaptureBoat,{captureIndex + 1},{capturePosition1.X},{capturePosition1.Y}";
                    else
                        sp.Message = $"CaptureBoat,{captureIndex + 1},{capturePosition2.X},{capturePosition2.Y}";
                    sp.PairRule = s => s.Contains("CaptureBoat");

                    if (captureIndex == 0)
                    {
                    retry:
                        TcpClientSendAndReceive(_vision, sp, 2000, 1, out string recvStr1);
                        if (!CheckFlowCondition()) return false;
                        if (recvStr1.Contains("NG"))
                        {
                            ShowWarnAndPause($"视觉{robotIndex}拍下料Boat回复NG，请检查视觉设定!", $"机器人{_moduleIndex + 1}模组");
                            if (!CheckFlowCondition()) return false;
                            string str = $"视觉{robotIndex}拍下料Boat回复NG,是否重试,'Yes'：重试,'No':下料Boat排出?";
                            Log(str);
                            if (MessageBox.Show(str, $"视觉{robotIndex}拍下料Boat", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                            {
                                Log("人为选择重试");
                                goto retry;
                            }
                            else
                            {
                                Log("人为选择下料Boat排出");
                                return false;
                            }
                        }
                        else if (recvStr1.Contains("OK"))
                        {
                            string[] strs = recvStr1.Split(',');
                            float boatc1x = Convert.ToSingle(strs[3]);
                            float boatc1y = Convert.ToSingle(strs[4]);
                            float boatp1x = Convert.ToSingle(strs[5]);
                            float boatp1y = Convert.ToSingle(strs[6]);

                            boatp1 = new PointF(boatp1x, boatp1y);
                            boatc1 = new PointF(boatc1x, boatc1y);
                        }
                        else
                        {
                            ShowWarnAndPause($"视觉{robotIndex}拍下料Boat回复异常，请检查视觉设定!", $"机器人{_moduleIndex + 1}模组");
                            if (!CheckFlowCondition()) return false;
                            goto retry;

                        }
                    }
                    else
                    {
                    retry:
                        TcpClientSendAndReceive(_vision, sp, 2000, 1, out string recvStr1);
                        if (!CheckFlowCondition()) return false;
                        if (recvStr1.Contains("NG"))
                        {
                            ShowWarnAndPause($"视觉{robotIndex}拍下料Boat回复NG，请检查视觉设定!", $"机器人{_moduleIndex + 1}模组");
                            if (!CheckFlowCondition()) return false;
                            string str = $"视觉{robotIndex}拍下料Boat回复NG,是否重试,'Yes'：重试,'No':下料Boat排出?";
                            Log(str);
                            if (MessageBox.Show(str, $"视觉{robotIndex}拍下料Boat", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                            {
                                Log("人为选择重试");
                                goto retry;
                            }
                            else
                            {
                                Log("人为选择下料Boat排出");
                                return false;
                            }
                        }
                        else if (recvStr1.Contains("OK"))
                        {
                            string[] strs = recvStr1.Split(',');
                            float boatc2x = Convert.ToSingle(strs[3]);
                            float boatc2y = Convert.ToSingle(strs[4]);
                            float boatp2x = Convert.ToSingle(strs[5]);
                            float boatp2y = Convert.ToSingle(strs[6]);

                            boatp2 = new PointF(boatp2x, boatp2y);
                            boatc2 = new PointF(boatc2x, boatc2y);

                            affineTransRobotGetPositions(boat1Positions,
                                                         boatp1, boatp2,
                                                         boatc1, boatc2,
                                                        _moduleIndex == 0 ? SystemConfig.Instance.UsingStatus.RecycleTrayCompensationX : SystemConfig.Instance.UsingStatus.RecycleTrayCompensationXRobot2,
                                                        _moduleIndex == 0 ? SystemConfig.Instance.UsingStatus.RecycleTrayCompensationY : SystemConfig.Instance.UsingStatus.RecycleTrayCompensationYRobot2,
                                                         out boat1TransPositions);
                            affineTransRobotGetPositions(boat2Positions,
                                                         boatp1, boatp2,
                                                         boatc1, boatc2,
                                                        _moduleIndex == 0 ? SystemConfig.Instance.UsingStatus.RecycleTrayCompensationX : SystemConfig.Instance.UsingStatus.RecycleTrayCompensationXRobot2,
                                                        _moduleIndex == 0 ? SystemConfig.Instance.UsingStatus.RecycleTrayCompensationY : SystemConfig.Instance.UsingStatus.RecycleTrayCompensationYRobot2,
                                                         out boat2TransPositions);
                        }
                        else
                        {
                            ShowWarnAndPause($"视觉{robotIndex}拍下料Boat回复异常，请检查视觉设定!", $"机器人{_moduleIndex + 1}模组");
                            if (!CheckFlowCondition()) return false;
                            goto retry;
                        }
                    }
                    #endregion
                }
                catch (Exception ex)
                {
                    LogHelper.Instance.Log("system", "数据解析异常", MessageLevel.Error, ex);
                    ShowWarnAndPause($"视觉{robotIndex}拍下料Boat异常,将进行强制下Boat!", $"机器人{_moduleIndex + 1}模组");
                    return false;
                }
            }
            return true;
        }

        PointF feedp1;
        PointF feedc1;
        PointF feedp2;
        PointF feedc2;
        public void VisionCaptureTray(int captureIndex)
        {
            if ((GlobalVariable.IsDryRun || SystemConfig.Instance.UsingStatus.IsVisionSimulate) && captureIndex == 1)
            {
                feedTransPositions = new List<RobotPoint>();
                for (int i = 0; i < feedPositions.Count; i++)
                {
                    feedTransPositions.Add(feedPositions[i]);
                }
                Thread.Sleep(500);
                return;
            }

            if (!SystemConfig.Instance.UsingStatus.IsVisionSimulate && !GlobalVariable.IsDryRun)
            {
                SendPackage sp = new SendPackage();
                if (captureIndex == 0)
                    sp.Message = $"CaptureFeed,{captureIndex + 1},{capturePositionFeed1.X},{capturePositionFeed1.Y}";
                else
                    sp.Message = $"CaptureFeed,{captureIndex + 1},{capturePositionFeed2.X},{capturePositionFeed2.Y}";
                sp.PairRule = null;

                if (captureIndex == 0)
                {
                retry:
                    TcpClientSendAndReceive(_vision, sp, 2000, 1, out string recvStr1);
                    if (!CheckFlowCondition()) return;
                    if (recvStr1.Contains("NG"))
                    {
                        ShowWarnAndPause("视觉拍上料Tray回复NG，请检查视觉设定!", $"机器人{_moduleIndex + 1}模组");
                        if (!CheckFlowCondition()) return;
                        goto retry;
                    }
                    else if (recvStr1.Contains("OK"))
                    {
                        string[] strs = recvStr1.Split(',');
                        float feedc1x = Convert.ToSingle(strs[3]);
                        float feedc1y = Convert.ToSingle(strs[4]);
                        float feedp1x = Convert.ToSingle(strs[5]);
                        float feedp1y = Convert.ToSingle(strs[6]);

                        feedp1 = new PointF(feedp1x, feedp1y);
                        feedc1 = new PointF(feedc1x, feedc1y);
                    }
                    else
                    {
                        ShowWarnAndPause("视觉拍上料Tray回复异常，请检查视觉设定!", $"机器人{_moduleIndex + 1}模组");
                        if (!CheckFlowCondition()) return;
                        goto retry;
                    }
                }
                else
                {
                retry:
                    TcpClientSendAndReceive(_vision, sp, 2000, 1, out string recvStr1);
                    if (!CheckFlowCondition()) return;
                    if (recvStr1.Contains("NG"))
                    {
                        ShowWarnAndPause("视觉拍上料Tray回复NG，请检查视觉设定!", $"机器人{_moduleIndex + 1}模组");
                        if (!CheckFlowCondition()) return;
                        goto retry;
                    }
                    else if (recvStr1.Contains("OK"))
                    {
                        string[] strs = recvStr1.Split(',');
                        float feedc2x = Convert.ToSingle(strs[3]);
                        float feedc2y = Convert.ToSingle(strs[4]);
                        float feedp2x = Convert.ToSingle(strs[5]);
                        float feedp2y = Convert.ToSingle(strs[6]);

                        feedp2 = new PointF(feedp2x, feedp2y);
                        feedc2 = new PointF(feedc2x, feedc2y);

                        affineTransRobotGetPositions(feedPositions,
                                                     feedp1, feedp2,
                                                     feedc1, feedc2,
                                                     _moduleIndex == 0 ? SystemConfig.Instance.UsingStatus.FeedTrayCompensationX : SystemConfig.Instance.UsingStatus.FeedTrayCompensationXRobot2,
                                                     _moduleIndex == 0 ? SystemConfig.Instance.UsingStatus.FeedTrayCompensationY : SystemConfig.Instance.UsingStatus.FeedTrayCompensationYRobot2,
                                                     out feedTransPositions);
                        //affineTransRobotGetPositions(feedPositions,
                        //                             feedp1, feedp2,
                        //                             feedc1, feedc2,
                        //                             0,
                        //                             -0.5,
                        //                             out feedTransPositions);
                    }
                    else
                    {
                        ShowWarnAndPause("视觉拍上料Tray回复异常，请检查视觉设定!", $"机器人{_moduleIndex + 1}模组");
                        if (!CheckFlowCondition()) return;
                        goto retry;
                    }
                }
            }
        }
        public void affineTransRobotGetPositions(List<RobotPoint> boatPos,
                                                 PointF p1, PointF p2,
                                                 PointF c1, PointF c2,
                                                 double offsetX, double offsetY,
                                                 out List<RobotPoint> boatTransPos)
        {
            boatTransPos = new List<RobotPoint>();

            HTuple angle = new HTuple();
            HOperatorSet.AngleLl(p1.X, p1.Y, p2.X, p2.Y, c1.X, c1.Y, c2.X, c2.Y, out angle);
            HTuple hommat2d = new HTuple();
            HOperatorSet.HomMat2dIdentity(out hommat2d);
            HTuple hommat2dRotate = new HTuple();
            HOperatorSet.HomMat2dRotate(hommat2d, -angle, p1.X, p1.Y, out hommat2dRotate);
            HTuple hommat2dTranslate = new HTuple();
            HOperatorSet.HomMat2dTranslate(hommat2dRotate, -c1.X + p1.X, -c1.Y + p1.Y, out hommat2dTranslate);
            double[] x1 = boatPos.Select(p => p.X).ToArray();
            double[] y1 = boatPos.Select(p => p.Y).ToArray();
            HTuple oldX1 = new HTuple(x1);
            HTuple oldY1 = new HTuple(y1);
            HTuple newX1, newY1;
            HOperatorSet.AffineTransPoint2d(hommat2dTranslate, oldX1, oldY1, out newX1, out newY1);
            for (int i = 0; i < newX1.Length; i++)
            {
                boatTransPos.Add(new RobotPoint(Convert.ToDouble(newX1[i].D.ToString("0.000")) + offsetX, Convert.ToDouble(newY1[i].D.ToString("0.000")) + offsetY, boatPos[i].R));
            }
        }
        public void affineTransRobotGetPositions2(List<RobotPoint> boatPos,
                                                 PointF p1, PointF p2,
                                                 PointF c1, PointF c2,
                                                 out List<RobotPoint> boatTransPos)
        {
            boatTransPos = new List<RobotPoint>();

            HTuple angle = new HTuple();
            HOperatorSet.AngleLl(p1.X, p1.Y, p2.X, p2.Y, c1.X, c1.Y, c2.X, c2.Y, out angle);
            HTuple hommat2d = new HTuple();
            HOperatorSet.HomMat2dIdentity(out hommat2d);
            HTuple hommat2dRotate = new HTuple();
            HOperatorSet.HomMat2dRotate(hommat2d, -angle, p1.X, p1.Y, out hommat2dRotate);
            HTuple hommat2dTranslate = new HTuple();
            HOperatorSet.HomMat2dTranslate(hommat2dRotate, c1.X - p1.X, -c1.Y + p1.Y, out hommat2dTranslate);
            double[] x1 = boatPos.Select(p => p.X).ToArray();
            double[] y1 = boatPos.Select(p => p.Y).ToArray();
            HTuple oldX1 = new HTuple(x1);
            HTuple oldY1 = new HTuple(y1);
            HTuple newX1, newY1;
            HOperatorSet.AffineTransPoint2d(hommat2dTranslate, oldX1, oldY1, out newX1, out newY1);
            for (int i = 0; i < newX1.Length; i++)
            {
                boatTransPos.Add(new RobotPoint(Convert.ToDouble(newX1[i].D.ToString("0.000")), Convert.ToDouble(newY1[i].D.ToString("0.000")), boatPos[i].R));
            }
        }
        public void PutOKBoat1(int putIndex, Tray okTray, bool isFrist, bool hasPutTwoTray)
        {
            //********************************
            //需要确认   机械手  boat1是用 3 7吸嘴还是 用 4 8吸嘴放的
            //**********************************
            List<int> sts = new List<int>();
            //3,7吸嘴
            sts.Add(_robotRecycleTray.Helper.GetCell(0).Status == CellStatus.HasProduct ? 1 : 0);
            sts.Add(_robotRecycleTray.Helper.GetCell(2).Status == CellStatus.HasProduct ? 1 : 0);
            UpdateOutput(sts);
            //sts = new List<int>() { 1, 1 };
            if (sts.Any(s => s == 1))
            {
                if (isSimulate)
                {
                    Thread.Sleep(1000);
                }
                else
                {
                    //0:依旧  1：变更
                    RobotCommandRun($"PutTray,1,{putIndex},{boat1TransPositions[putIndex]},{sts[0]},{sts[1]},{(isFrist ? "0" : "1")},{(hasPutTwoTray ? "1" : "0")}",
                                    $"机械手{_moduleIndex + 1}放下料Boat失败",
                                    out string recvStr);
                    if (!CheckFlowCondition()) return;
                }

                //3吸嘴
                if (_robotRecycleTray.Helper.GetCell(0).Status == CellStatus.HasProduct)
                {
                    okTray.Helper.SetCellStatus(putIndex + 15, CellStatus.HasProduct);
                    okTray.Helper.SetCellBarcode(putIndex + 15, _robotRecycleTray.Helper.GetCell(0).SN);
                    okTray.Helper.SetCellResult(putIndex + 15, _robotRecycleTray.Helper.GetCell(0).Result);

                    if (SystemConfig.Instance.MesParam.EnableMES)
                    {
                        //3吸嘴从下料boat第16位开始放，前模组放的是靠里的boat
                        if (_moduleIndex == 0)
                        {
                        rebind:
                            //GlobalVariable.CurrentFrontOKBoatSN = "CSF-U66-21AOB1-048";
                            if (!CommonMethod.DoCarrierBind(_robotRecycleTray.Helper.GetCell(0).SN, $"{46 + putIndex}", GlobalVariable.CurrentFrontOKBoatSN, out string errInfo))
                            {
                                ShowWarnAndPause($"下料绑码失败!原因:{errInfo}", "系统");
                                if (!CheckFlowCondition()) return;
                                if (MessageBox.Show("是否重试", "MES", MessageBoxButtons.YesNo) == DialogResult.Yes)
                                {
                                    goto rebind;
                                }
                            }
                        }
                        else
                        {
                        rebind:
                            if (!CommonMethod.DoCarrierBind(_robotRecycleTray.Helper.GetCell(0).SN, $"{putIndex + 1}", GlobalVariable.CurrentBackOKBoatSN, out string errInfo))
                            {
                                ShowWarnAndPause($"下料绑码失败!原因:{errInfo}", "系统");
                                if (!CheckFlowCondition()) return;
                                if (MessageBox.Show("是否重试", "MES", MessageBoxButtons.YesNo) == DialogResult.Yes)
                                {
                                    goto rebind;
                                }
                            }
                        }
                    }

                    _robotRecycleTray.Helper.SetCellStatus(0, CellStatus.NoProduct);
                    _robotRecycleTray.Helper.SetCellBarcode(0, string.Empty);
                    _robotRecycleTray.Helper.SetCellResult(0, TestResult.NoTest);

                    _robotTotalTray.Helper.SetCellStatus(2, CellStatus.NoProduct);
                }
                //7吸嘴
                if (_robotRecycleTray.Helper.GetCell(2).Status == CellStatus.HasProduct)
                {
                    okTray.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
                    okTray.Helper.SetCellBarcode(putIndex, _robotRecycleTray.Helper.GetCell(2).SN);
                    okTray.Helper.SetCellResult(putIndex, _robotRecycleTray.Helper.GetCell(2).Result);

                    if (SystemConfig.Instance.MesParam.EnableMES)
                    {
                        //7吸嘴从下料boat第1位开始放，前模组放的是靠里的boat
                        if (_moduleIndex == 0)
                        {
                        rebind:
                            if (!CommonMethod.DoCarrierBind(_robotRecycleTray.Helper.GetCell(2).SN, $"{31 + putIndex}", GlobalVariable.CurrentFrontOKBoatSN, out string errInfo))
                            {
                                ShowWarnAndPause($"下料绑码失败!原因:{errInfo}", "系统");
                                if (!CheckFlowCondition()) return;
                                if (MessageBox.Show("是否重试", "MES", MessageBoxButtons.YesNo) == DialogResult.Yes)
                                {
                                    goto rebind;
                                }
                            }
                        }
                        else
                        {
                        rebind:
                            if (!CommonMethod.DoCarrierBind(_robotRecycleTray.Helper.GetCell(2).SN, $"{16 + putIndex}", GlobalVariable.CurrentBackOKBoatSN, out string errInfo))
                            {
                                ShowWarnAndPause($"下料绑码失败!原因:{errInfo}", "系统");
                                if (!CheckFlowCondition()) return;
                                if (MessageBox.Show("是否重试", "MES", MessageBoxButtons.YesNo) == DialogResult.Yes)
                                {
                                    goto rebind;
                                }
                            }
                        }
                    }

                    _robotRecycleTray.Helper.SetCellStatus(2, CellStatus.NoProduct);
                    _robotRecycleTray.Helper.SetCellBarcode(2, string.Empty);
                    _robotRecycleTray.Helper.SetCellResult(2, TestResult.NoTest);

                    _robotTotalTray.Helper.SetCellStatus(0, CellStatus.NoProduct);
                }
                _recycleHalfTray1.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
            }
        }
        public void UpdateOutput(List<int> sts)
        {
            lock (GlobalVariable.FrontBackOutputDataLock)
            {
                GlobalVariable.CurrentMachineData.TotalOutputCount += sts.Count(s => s == 1);
            }
            lock (GlobalVariable.TesterOKDataLock)
            {
                GlobalVariable.CurrentMachineData.TotalOKCount += sts.Count(s => s == 1);
            }
            GlobalVariable.SaveMachineData(GlobalVariable.CurrentMachineData);
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Count, GlobalVariable.CurrentMachineData.TotalOutputCount.ToString(), this.Description, 0, "Output"));
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Count, GlobalVariable.CurrentMachineData.TotalOKCount.ToString(), this.Description, 0, "OK"));
        }
        public void PutOKBoat2(int putIndex, Tray okTray, bool isFrist, bool hasPutTwoTray)
        {
            List<int> sts = new List<int>();
            //吸嘴4 和 8
            sts.Add(_robotRecycleTray.Helper.GetCell(1).Status == CellStatus.HasProduct ? 1 : 0);
            sts.Add(_robotRecycleTray.Helper.GetCell(3).Status == CellStatus.HasProduct ? 1 : 0);
            UpdateOutput(sts);
            //sts = new List<int>() { 1, 1 };
            if (sts.Any(s => s == 1))
            {
                if (isSimulate)
                {
                    Thread.Sleep(1000);
                }
                else
                {
                    //0:照旧  1：变更
                    RobotCommandRun($"PutTray,2,{putIndex},{boat2TransPositions[putIndex]},{sts[0]},{sts[1]},{(isFrist ? "0" : "1")},{(hasPutTwoTray ? "1" : "0")}",
                                    $"机械手{_moduleIndex + 1}放下料Boat失败",
                                    out string recvStr);
                    if (!CheckFlowCondition()) return;
                }

                if (_robotRecycleTray.Helper.GetCell(1).Status == CellStatus.HasProduct)
                {
                    okTray.Helper.SetCellStatus(putIndex + 15, CellStatus.HasProduct);
                    okTray.Helper.SetCellBarcode(putIndex + 15, _robotRecycleTray.Helper.GetCell(1).SN);
                    okTray.Helper.SetCellResult(putIndex + 15, _robotRecycleTray.Helper.GetCell(1).Result);

                    if (SystemConfig.Instance.MesParam.EnableMES)
                    {
                        //4吸嘴从下料boat第46位开始放，前模组放的是靠外的boat
                        if (_moduleIndex == 0)
                        {
                        rebind:
                            if (!CommonMethod.DoCarrierBind(_robotRecycleTray.Helper.GetCell(1).SN, $"{16 + putIndex}", GlobalVariable.CurrentFrontOKBoatSN, out string errInfo))
                            {
                                ShowWarnAndPause($"下料绑码失败!原因:{errInfo}", "系统");
                                if (!CheckFlowCondition()) return;
                                if (MessageBox.Show("是否重试", "MES", MessageBoxButtons.YesNo) == DialogResult.Yes)
                                {
                                    goto rebind;
                                }
                            }
                        }
                        else
                        {
                        rebind:
                            if (!CommonMethod.DoCarrierBind(_robotRecycleTray.Helper.GetCell(1).SN, $"{31 + putIndex}", GlobalVariable.CurrentBackOKBoatSN, out string errInfo))
                            {
                                ShowWarnAndPause($"下料绑码失败!原因:{errInfo}", "系统");
                                if (!CheckFlowCondition()) return;
                                if (MessageBox.Show("是否重试", "MES", MessageBoxButtons.YesNo) == DialogResult.Yes)
                                {
                                    goto rebind;
                                }
                            }
                        }
                    }

                    _robotRecycleTray.Helper.SetCellStatus(1, CellStatus.NoProduct);
                    _robotRecycleTray.Helper.SetCellBarcode(1, string.Empty);
                    _robotRecycleTray.Helper.SetCellResult(1, TestResult.NoTest);

                    _robotTotalTray.Helper.SetCellStatus(6, CellStatus.NoProduct);
                }
                if (_robotRecycleTray.Helper.GetCell(3).Status == CellStatus.HasProduct)
                {
                    okTray.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
                    okTray.Helper.SetCellBarcode(putIndex, _robotRecycleTray.Helper.GetCell(3).SN);
                    okTray.Helper.SetCellResult(putIndex, _robotRecycleTray.Helper.GetCell(3).Result);

                    if (SystemConfig.Instance.MesParam.EnableMES)
                    {
                        //8吸嘴从下料boat第31位开始放，前模组放的是靠外的boat
                        if (_moduleIndex == 0)
                        {
                        rebind:
                            if (!CommonMethod.DoCarrierBind(_robotRecycleTray.Helper.GetCell(3).SN, $"{1 + putIndex}", GlobalVariable.CurrentFrontOKBoatSN, out string errInfo))
                            {
                                ShowWarnAndPause($"下料绑码失败!原因:{errInfo}", "系统");
                                if (!CheckFlowCondition()) return;
                                if (MessageBox.Show("是否重试", "MES", MessageBoxButtons.YesNo) == DialogResult.Yes)
                                {
                                    goto rebind;
                                }
                            }
                        }
                        else
                        {
                        rebind:
                            if (!CommonMethod.DoCarrierBind(_robotRecycleTray.Helper.GetCell(3).SN, $"{46 + putIndex}", GlobalVariable.CurrentBackOKBoatSN, out string errInfo))
                            {
                                ShowWarnAndPause($"下料绑码失败!原因:{errInfo}", "系统");
                                if (!CheckFlowCondition()) return;
                                if (MessageBox.Show("是否重试", "MES", MessageBoxButtons.YesNo) == DialogResult.Yes)
                                {
                                    goto rebind;
                                }
                            }
                        }
                    }

                    _robotRecycleTray.Helper.SetCellStatus(3, CellStatus.NoProduct);
                    _robotRecycleTray.Helper.SetCellBarcode(3, string.Empty);
                    _robotRecycleTray.Helper.SetCellResult(3, TestResult.NoTest);

                    _robotTotalTray.Helper.SetCellStatus(4, CellStatus.NoProduct);
                }
                _recycleHalfTray2.Helper.SetCellStatus(putIndex, CellStatus.HasProduct);
            }
        }
        public void CarrierBind(int bindIndex)
        {
            //CommonMethod.DoCarrierBind()
        }
        public Tray GetTotalTray()
        {
            return _robotTotalTray;
        }
        public void RobotCommandRun(string message, string errInfo, out string recvStr)
        {
            recvStr = "";
            SendPackage sp = new SendPackage();
            sp.Message = message + ",\r\n";
            TcpClientSend(_robot, sp);
            if (!CheckFlowCondition()) return;
            wait:
            TcpClientWait(_robot, sp, 60000, out recvStr);
            if (recvStr.Contains("Welcome"))
            {
                sp.SendFlag = false;
                _robot.AddPackage(sp);
                goto wait;
            }
            if (!CheckFlowCondition()) return;
            if (recvStr.Contains("NG"))
            {
                sp.SendFlag = false;
                _robot.AddPackage(sp);
                ShowWarnAndPause(errInfo, $"机器人{_moduleIndex + 1}模组");
                if (!CheckFlowCondition()) return;
                goto wait;
            }
            else if (recvStr.Contains("ERROR"))
            {
                sp.SendFlag = false;
                _robot.AddPackage(sp);
                ShowWarnAndPause(errInfo, $"机器人{_moduleIndex + 1}模组");
                if (!CheckFlowCondition()) return;
                goto wait;
            }
            else if (recvStr.Contains("OK"))
            {
                sp.SendFlag = false;
            }
            else
            {
                sp.SendFlag = false;
                _robot.AddPackage(sp);
                ShowWarnAndPause("机器人回复指令异常", $"机器人{_moduleIndex + 1}模组");
                if (!CheckFlowCondition()) return;
                goto wait;
            }
        }


        public List<int> RobotCommandRunAndOPCheck(string message, List<int> comm, string errInfo, out string recvStr)
        {
            recvStr = "";
            string oldStr = message;
            List<int> oldComm = comm;
        wait:
            _robot.ClearPackage();
            SendPackage sp = new SendPackage();
            sp.Message = $"{message},{string.Join(",", comm)}" + ",\r\n";
            TcpClientSend(_robot, sp);
            if (!CheckFlowCondition()) return oldComm;
            TcpClientWait(_robot, sp, 60000, out recvStr);
            if (recvStr.Contains("Welcome"))
            {
                sp.SendFlag = false;
                _robot.AddPackage(sp);
                goto wait;
            }
            if (!CheckFlowCondition()) return oldComm;
            if (recvStr.Contains("NG"))
            {
                sp.SendFlag = false;
                _robot.AddPackage(sp);
                ShowWarnAndPause(errInfo, $"机器人{_moduleIndex + 1}模组");
                if (!CheckFlowCondition()) return oldComm;
                List<int> tip = MessageBoxExRobot.ShowBox($"机器人{_moduleIndex + 1}模组:上料取料失败,取料穴位如下，请人员确定是否与实际取料穴位一致?,点击‘取消’不进行重新取料。",
                    "上料机械手取料", oldComm, MessageBoxType.Info, out bool cancel);
                comm = tip;
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机器人{_moduleIndex + 1}模组:上料取料指令：{string.Join(",", oldComm)},人为选择：{string.Join(",", comm)}{(cancel ? "，点击取消" : "")}", this.Description, 0, ""));
                if (!cancel)
                    goto wait;
            }
            else if (recvStr.Contains("Error"))
            {
                sp.SendFlag = false;
                _robot.AddPackage(sp);
                ShowWarnAndPause(errInfo, $"机器人{_moduleIndex + 1}模组");
                if (!CheckFlowCondition()) return oldComm;
                List<int> tip = MessageBoxExRobot.ShowBox($"机器人{_moduleIndex + 1}模组:上料取料指令与实际穴位不符,取料穴位如下，请人员确定是否与实际取料穴位一致？",
                   "上料机械手取料", oldComm, MessageBoxType.Info, out bool cancel);
                comm = tip;
                MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机器人{_moduleIndex + 1}模组:上料取料指令：{string.Join(",", oldComm)},人为选择：：{string.Join(",", comm)}", this.Description, 0, ""));
                goto wait;
            }
            else if (recvStr.Contains("OK"))
            {
                sp.SendFlag = false;
            }
            else
            {
                sp.SendFlag = false;
                _robot.AddPackage(sp);
                ShowWarnAndPause("机器人回复指令异常", $"机器人{_moduleIndex + 1}模组");
                if (!CheckFlowCondition()) return oldComm;
                goto wait;
            }
            return comm;
        }



        public bool AllTesterNoProduct()
        {
            int moduleIndex = 0;
            List<Tray> testerTrays = new List<Tray>();
            testerTrays.Add((_flowManager.SelectFlow($"测试模组{moduleIndex + 1}1") as TesterLogic).TesterTray);
            testerTrays.Add((_flowManager.SelectFlow($"测试模组{moduleIndex + 1}2") as TesterLogic).TesterTray);
            testerTrays.Add((_flowManager.SelectFlow($"测试模组{moduleIndex + 1}3") as TesterLogic).TesterTray);
            bool noProduct = true;
            for (int i = 0; i < testerTrays.Count; i++)
            {
                if (testerTrays[i].Helper.Any(c => c.Status == CellStatus.HasProduct))
                {
                    noProduct = false;
                    break;
                }
            }
            if (!noProduct)
                return noProduct;

            moduleIndex = 1;
            testerTrays = new List<Tray>();
            testerTrays.Add((_flowManager.SelectFlow($"测试模组{moduleIndex + 1}1") as TesterLogic).TesterTray);
            testerTrays.Add((_flowManager.SelectFlow($"测试模组{moduleIndex + 1}2") as TesterLogic).TesterTray);
            testerTrays.Add((_flowManager.SelectFlow($"测试模组{moduleIndex + 1}3") as TesterLogic).TesterTray);
            noProduct = true;
            for (int i = 0; i < testerTrays.Count; i++)
            {
                if (testerTrays[i].Helper.Any(c => c.Status == CellStatus.HasProduct))
                {
                    noProduct = false;
                    break;
                }
            }
            return noProduct;
        }
        public bool AllArmNoProduct()
        {
            if (_moduleIndex == 0)
            {
                bool arm1HasProduct = (_flowManager.SelectFlow($"Arm1模组") as TransferLogic).GetFeedTray().Helper.Any(c => c.Status == CellStatus.HasProduct);
                bool arm2HasProduct = (_flowManager.SelectFlow($"Arm2模组") as TransferLogic).GetFeedTray().Helper.Any(c => c.Status == CellStatus.HasProduct);
                bool arm1HasProduct2 = (_flowManager.SelectFlow($"Arm1模组") as TransferLogic).GetRecycleTray().Helper.Any(c => c.Status == CellStatus.HasProduct);
                bool arm2HasProduct2 = (_flowManager.SelectFlow($"Arm2模组") as TransferLogic).GetRecycleTray().Helper.Any(c => c.Status == CellStatus.HasProduct);

                return !(arm1HasProduct || arm2HasProduct || arm1HasProduct2 || arm2HasProduct2);
            }
            else
            {
                bool arm3HasProduct = (_flowManager.SelectFlow($"Arm3模组") as TransferLogic).GetFeedTray().Helper.Any(c => c.Status == CellStatus.HasProduct);
                bool arm4HasProduct = (_flowManager.SelectFlow($"Arm4模组") as TransferLogic).GetFeedTray().Helper.Any(c => c.Status == CellStatus.HasProduct);
                bool arm3HasProduct2 = (_flowManager.SelectFlow($"Arm3模组") as TransferLogic).GetRecycleTray().Helper.Any(c => c.Status == CellStatus.HasProduct);
                bool arm4HasProduct2 = (_flowManager.SelectFlow($"Arm4模组") as TransferLogic).GetRecycleTray().Helper.Any(c => c.Status == CellStatus.HasProduct);

                return !(arm3HasProduct || arm4HasProduct || arm3HasProduct2 || arm4HasProduct2);
            }
        }
        public bool AllPrecisionNoProduct()
        {
            bool feed1UpHasProduct = (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetFeedTray1Up().Helper.Any(c => c.Status == CellStatus.HasProduct);
            bool feed2UpHasProduct = (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetFeedTray2Up().Helper.Any(c => c.Status == CellStatus.HasProduct);
            bool recyle1UpHasProduct = (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetRecycleTray1Up().Helper.Any(c => c.Status == CellStatus.HasProduct);
            bool recyle2UpHasProduct = (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetRecycleTray2Up().Helper.Any(c => c.Status == CellStatus.HasProduct);
            bool feed1DownHasProduct = (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetFeedTray1Down().Helper.Any(c => c.Status == CellStatus.HasProduct);
            bool feed2DownHasProduct = (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetFeedTray2Down().Helper.Any(c => c.Status == CellStatus.HasProduct);
            bool recyle1DownHasProduct = (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetRecycleTray1Down().Helper.Any(c => c.Status == CellStatus.HasProduct);
            bool recyle2DownHasProduct = (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetRecycleTray2Down().Helper.Any(c => c.Status == CellStatus.HasProduct);
            return !(feed1UpHasProduct ||
                     feed2UpHasProduct ||
                     recyle1UpHasProduct ||
                     recyle2UpHasProduct ||
                     feed1DownHasProduct ||
                     feed2DownHasProduct ||
                     recyle1DownHasProduct ||
                     recyle2DownHasProduct);
        }
        public bool AllRobotNoProdcut()
        {
            bool robotFeedHasProduct = _robotFeedTray.Helper.Any(c => c.Status == CellStatus.HasProduct);
            bool robotRecycleHasProduct = _robotRecycleTray.Helper.Any(c => c.Status == CellStatus.HasProduct);
            return !(robotFeedHasProduct || robotRecycleHasProduct);
        }
        public Tray GetFeedTray()
        {
            return _robotFeedTray;
        }
        public Tray GetRecycleTray()
        {
            return _robotRecycleTray;
        }
        //getMode = 0 只取前一半
        //          1 只取后一半
        //          2 全部取
        //          3 先取一半 再取一半
        public (int, int) GetFeedTrayGetIndex(out int getMode)
        {
            int disableStatus = 0;
            getMode = -1;

            if (_moduleIndex == 0)
            {
                if (SystemConfig.Instance.UsingStatus.ArmInUseStatus[0] &&
                    !SystemConfig.Instance.UsingStatus.ArmInUseStatus[1])
                {
                    disableStatus = 1;
                    //这种情况下，只能取前一半
                }
                else if (!SystemConfig.Instance.UsingStatus.ArmInUseStatus[0] &&
                        SystemConfig.Instance.UsingStatus.ArmInUseStatus[1])
                {
                    disableStatus = 2;
                    //这种情况下，只能取后一半
                }
            }
            else
            {
                if (SystemConfig.Instance.UsingStatus.ArmInUseStatus[2] &&
                    !SystemConfig.Instance.UsingStatus.ArmInUseStatus[3])
                {
                    disableStatus = 1;
                    //这种情况下，只能取前一半
                }
                else if (!SystemConfig.Instance.UsingStatus.ArmInUseStatus[2] &&
                        SystemConfig.Instance.UsingStatus.ArmInUseStatus[3])
                {
                    disableStatus = 2;
                    //这种情况下，只能取后一半
                }
            }

            if (disableStatus == 0)
            {
                for (int i = 0; i < 30; i++)
                {
                    if (_feedHalfTray1.Helper.GetCell(i).Status == CellStatus.HasProduct &&
                        _feedHalfTray2.Helper.GetCell(i).Status == CellStatus.HasProduct)
                    {
                        List<bool> status = new List<bool>();
                        //结合视觉看看
                        if (i < 15)
                        {
                            status.Add(feedTray.Helper.GetCell(i).Status == CellStatus.HasProduct);
                            status.Add(feedTray.Helper.GetCell(i + 60).Status == CellStatus.HasProduct);
                            status.Add(feedTray.Helper.GetCell(i + 15).Status == CellStatus.HasProduct);
                            status.Add(feedTray.Helper.GetCell(i + 60 + 15).Status == CellStatus.HasProduct);
                        }
                        else
                        {
                            status.Add(feedTray.Helper.GetCell(15 + i).Status == CellStatus.HasProduct);
                            status.Add(feedTray.Helper.GetCell(15 + i + 60).Status == CellStatus.HasProduct);
                            status.Add(feedTray.Helper.GetCell(15 + i + 15).Status == CellStatus.HasProduct);
                            status.Add(feedTray.Helper.GetCell(15 + i + 60 + 15).Status == CellStatus.HasProduct);
                        }
                        if (status.Count(s => s) < 3)
                            continue;
                        getMode = 2;
                        return (i, i);
                    }
                }

                for (int i = 0; i < 30; i++)
                {
                    if (_feedHalfTray1.Helper.GetCell(i).Status == CellStatus.HasProduct)
                    {
                        for (int j = 0; j < 30; j++)
                        {
                            if (_feedHalfTray2.Helper.GetCell(j).Status == CellStatus.HasProduct)
                            {
                                List<bool> status1 = new List<bool>();
                                if (i < 15)
                                {
                                    status1.Add(feedTray.Helper.GetCell(i).Status == CellStatus.HasProduct);
                                    status1.Add(feedTray.Helper.GetCell(i + 60).Status == CellStatus.HasProduct);
                                }
                                else
                                {
                                    status1.Add(feedTray.Helper.GetCell(15 + i).Status == CellStatus.HasProduct);
                                    status1.Add(feedTray.Helper.GetCell(15 + i + 60).Status == CellStatus.HasProduct);
                                }

                                List<bool> status2 = new List<bool>();
                                if (j < 15)
                                {
                                    status2.Add(feedTray.Helper.GetCell(j + 15).Status == CellStatus.HasProduct);
                                    status2.Add(feedTray.Helper.GetCell(j + 60 + 15).Status == CellStatus.HasProduct);
                                }
                                else
                                {
                                    status2.Add(feedTray.Helper.GetCell(15 + j + 15).Status == CellStatus.HasProduct);
                                    status2.Add(feedTray.Helper.GetCell(15 + j + 60 + 15).Status == CellStatus.HasProduct);
                                }
                                //前2和后2吸嘴各至少有1个 才算模式3
                                if (status1.Count(c => c) > 0 && status2.Count(c => c) > 0)
                                {
                                    getMode = 3;
                                    return (i, j);
                                }
                            }
                        }
                    }
                }
            }

            if (disableStatus != 2)
            {
                for (int index = 0; index < 30; index++)
                {
                    if (_feedHalfTray1.Helper.GetCell(index).Status == CellStatus.HasProduct)
                    {
                        List<bool> status = new List<bool>();
                        if (index < 15)
                        {
                            status.Add(feedTray.Helper.GetCell(index).Status == CellStatus.HasProduct);
                            status.Add(feedTray.Helper.GetCell(index + 60).Status == CellStatus.HasProduct);
                        }
                        else
                        {
                            status.Add(feedTray.Helper.GetCell(15 + index).Status == CellStatus.HasProduct);
                            status.Add(feedTray.Helper.GetCell(15 + index + 60).Status == CellStatus.HasProduct);
                        }
                        if (status.Count(s => s) > 0)
                        {
                            getMode = 0;
                            return (index, index);
                        }
                    }
                }
            }
            if (disableStatus != 1)
            {
                for (int index = 0; index < 30; index++)
                {
                    if (_feedHalfTray2.Helper.GetCell(index).Status == CellStatus.HasProduct)
                    {
                        List<bool> status = new List<bool>();
                        if (index < 15)
                        {
                            status.Add(feedTray.Helper.GetCell(index + 15).Status == CellStatus.HasProduct);
                            status.Add(feedTray.Helper.GetCell(index + 60 + 15).Status == CellStatus.HasProduct);
                        }
                        else
                        {
                            status.Add(feedTray.Helper.GetCell(15 + index + 15).Status == CellStatus.HasProduct);
                            status.Add(feedTray.Helper.GetCell(15 + index + 60 + 15).Status == CellStatus.HasProduct);
                        }
                        if (status.Count(s => s) > 0)
                        {
                            getMode = 1;
                            return (index, index);
                        }
                    }
                }

            }
            return (-1, -1);
        }
        public void ExchangeProductManual(bool isUp)
        {
            Tray recycle1 = isUp ? (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetRecycleTray1Up() : (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetRecycleTray1Down();
            Tray recycle2 = isUp ? (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetRecycleTray2Up() : (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetRecycleTray2Down();
            Tray feed1 = isUp ? (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetFeedTray1Up() : (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetFeedTray1Down();
            Tray feed2 = isUp ? (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetFeedTray2Up() : (_flowManager.SelectFlow($"精定位移载{_moduleIndex + 1}") as PrecisionLogic).GetFeedTray2Down();

            for (int i = 0; i < 2; i++)
            {
                recycle2.Helper.SetCellStatus(i, CellStatus.NoProduct);
                recycle2.Helper.SetCellBarcode(i, string.Empty);
                recycle2.Helper.SetCellResult(i, TestResult.NoTest);
            }
            for (int i = 0; i < 2; i++)
            {
                recycle1.Helper.SetCellStatus(i, CellStatus.NoProduct);
                recycle1.Helper.SetCellBarcode(i, string.Empty);
                recycle1.Helper.SetCellResult(i, TestResult.NoTest);
            }

            for (int i = 0; i < 2; i++)
            {
                feed2.Helper.SetCellStatus(i, CellStatus.HasProduct);
                if (i == 0)
                {
                    if (isUp)
                        feed2.Helper.SetCellBarcode(0, GlobalVariable.Robot2Up1Barcode);
                    else
                        feed2.Helper.SetCellBarcode(0, GlobalVariable.Robot2Down1Barcode);
                }
                if (i == 1)
                {
                    if (isUp)
                        feed2.Helper.SetCellBarcode(1, GlobalVariable.Robot2Up2Barcode);
                    else
                        feed2.Helper.SetCellBarcode(1, GlobalVariable.Robot2Down2Barcode);
                }
                feed2.Helper.SetCellResult(i, TestResult.NoTest);
            }
            for (int i = 2; i < 4; i++)
            {
                feed1.Helper.SetCellStatus(i - 2, CellStatus.HasProduct);
                if (i == 0)
                {
                    if (isUp)
                        feed1.Helper.SetCellBarcode(0, GlobalVariable.Robot2Up5Barcode);
                    else
                        feed1.Helper.SetCellBarcode(0, GlobalVariable.Robot2Down5Barcode);
                }
                if (i == 1)
                {
                    if (isUp)
                        feed1.Helper.SetCellBarcode(1, GlobalVariable.Robot2Up6Barcode);
                    else
                        feed1.Helper.SetCellBarcode(1, GlobalVariable.Robot2Down6Barcode);
                }
                feed1.Helper.SetCellResult(i - 2, TestResult.NoTest);
            }
        }
        public void checkProductStatus()
        {
        restart:
            for (int i = 0; i < _feedVacSenses.Count; i++)
            {
                if (_feedVacSenses[i].WaitOn())
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.InfoAndPause, $"机器人{_moduleIndex + 1}手上有料，请取走后关闭真空", this.Description, 0, "系统"));
                    //出错，停下所有线程
                    _flowManager.Pause();
                    //若为报错，需重新检测启动信号
                    WaitForStart();
                    if (!CheckFlowCondition()) return;
                    goto restart;
                }
            }
        }

        private void NotifyRobotSwitchProduct(int _moduleNum)
        {
            if (GlobalVariable.IsDryRun)
                return;
            bool configBool = Properties.Settings.Default.ConfigName == "Machine.xml";
            string recvString = "";
            if (configBool)
            {
                //if (MessageBox.Show($"根据当前配方，即将通知机械手{_moduleNum}切换为 薄 ", "机械手切换产品", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"用户确认机械手{_moduleNum}产品切换为 薄 ", "产品切换", 0, "产品切换"));
                reSend:
                    RobotCommandRun($"SwitchProduct,Thin", "", out recvString);
                    if (recvString.Replace("\r\n", "").Contains("SwitchProduct,Thin,OK"))
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleNum}产品切换为 薄 ：成功！", "产品切换", 0, "产品切换"));
                    }
                    else
                    {
                        if (MessageBox.Show($"机械手切换产品失败，再次通知机械手{_moduleNum}切换为 厚 ", "机械手切换产品", MessageBoxButtons.RetryCancel, MessageBoxIcon.Question) == DialogResult.Retry)
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"用户重试将机械手{_moduleNum}产品切换为 厚 ", "产品切换", 0, "产品切换"));
                            goto reSend;
                        }
                        else
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"用户放弃重试将机械手{_moduleNum}产品切换为 厚 ", "产品切换", 0, "产品切换"));
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleNum}产品切换为 厚 ：失败！", "产品切换", 0, "产品切换"));
                            GlobalVariable.HasNotifyRobotSwitch = false;
                        }
                    }
                }
                //else
                //{
                //    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"用户否认机械手{_moduleNum}产品切换为 薄 ", "产品切换", 0, "产品切换"));
                //    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleNum}产品切换为 薄 ：失败！", "产品切换", 0, "产品切换"));
                //    ShowWarnAndPause($"机械手{_moduleNum}切换产品尚未完成！", this.Description);
                //    GlobalVariable.HasNotifyRobotSwitch = false;
                //}
            }
            else
            {
                //if (MessageBox.Show($"根据当前配方，即将通知机械手{_moduleNum}切换为 厚 ", "机械手切换产品", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"用户确认机械手{_moduleNum}产品切换为 厚 ", "产品切换", 0, "产品切换"));
                reSend:
                    RobotCommandRun($"SwitchProduct,Thick", "", out recvString);
                    if (recvString.Replace("\r\n", "").Contains("SwitchProduct,Thick,OK"))
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleNum}产品切换为 厚 ：成功！", "产品切换", 0, "产品切换"));
                    }
                    else
                    {
                        if (MessageBox.Show($"机械手切换产品失败，再次通知机械手{_moduleNum}切换为 厚 ", "机械手切换产品", MessageBoxButtons.RetryCancel, MessageBoxIcon.Question) == DialogResult.Retry)
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"用户重试将机械手{_moduleNum}产品切换为 厚 ", "产品切换", 0, "产品切换"));
                            goto reSend;
                        }
                        else
                        {
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"用户放弃重试将机械手{_moduleNum}产品切换为 厚 ", "产品切换", 0, "产品切换"));
                            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleNum}产品切换为 厚 ：失败！", "产品切换", 0, "产品切换"));
                            GlobalVariable.HasNotifyRobotSwitch = false;
                        }
                    }
                }
                //else
                //{
                //    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"用户否认机械手{_moduleNum}产品切换为 厚 ", "产品切换", 0, "产品切换"));
                //    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"机械手{_moduleNum}产品切换为 厚 ：失败！", "产品切换", 0, "产品切换"));
                //    ShowWarnAndPause($"机械手{_moduleNum}切换产品尚未完成！", this.Description);
                //    GlobalVariable.HasNotifyRobotSwitch = false;
                //}
            }
        }

        private void DoPrecisionCylinder(bool isFeed, bool isUp, bool isClamp, bool isDelay = true, bool isEnable = true)
        {
            //if (_moduleIndex == 0)
            //{
            //    if (isUp)
            //    {
            //        if (isClamp)
            //        {
            //            if (isDelay)
            //                Thread.Sleep(SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInRobotUp);
            //            MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { true, true });
            //            if (isDelay)
            //                Thread.Sleep(SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInRobotUp);
            //        }
            //        else
            //        {
            //            if (isDelay)
            //                Thread.Sleep(SystemConfig.Instance.UsingStatus.ReleasePrecisionDelayBeforeInRobotUp);
            //            MultiCylinderOperate(new List<Cylinder>() { _upPositionCylinder1, _upPositionCylinder2 }, 5000, new List<bool>() { false, false });
            //            if (isDelay)
            //                Thread.Sleep(SystemConfig.Instance.UsingStatus.ReleasePrecisionDelayInRobotUp);
            //        }
            //    }
            //    else
            //    {
            //        if (isClamp)
            //        {
            //            if (isDelay)
            //                Thread.Sleep(SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInRobotDown);
            //            MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { true, true });
            //            if (isDelay)
            //                Thread.Sleep(SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInRobotDown);
            //        }
            //        else
            //        {
            //            if (isDelay)
            //                Thread.Sleep(SystemConfig.Instance.UsingStatus.ReleasePrecisionDelayBeforeInRobotDown);
            //            MultiCylinderOperate(new List<Cylinder>() { _downPositionCylinder1, _downPositionCylinder2 }, 5000, new List<bool>() { false, false });
            //            if (isDelay)
            //                Thread.Sleep(SystemConfig.Instance.UsingStatus.ReleasePrecisionDelayInRobotDown);
            //        }
            //    }
            //}
            //else
            {
                if (isEnable)
                {


                    if (isUp)
                    {
                        if (isClamp)
                        {
                            if (isDelay)
                                Thread.Sleep(SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInRobotUp);
                            if (isFeed)
                                MultiCylinderOperate(_upFeedPositionCylinder, 5000, new List<bool>() { true, true });
                            else
                                MultiCylinderOperate(_upRecyclePositionCylinder, 5000, new List<bool>() { true, true });
                            if (isDelay)
                                Thread.Sleep(SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInRobotUp);
                        }
                        else
                        {
                            if (isDelay)
                                Thread.Sleep(SystemConfig.Instance.UsingStatus.ReleasePrecisionDelayBeforeInRobotUp);
                            if (isFeed)
                                MultiCylinderOperate(_upFeedPositionCylinder, 5000, new List<bool>() { false, false });
                            else
                                MultiCylinderOperate(_upRecyclePositionCylinder, 5000, new List<bool>() { false, false });
                            if (isDelay)
                                Thread.Sleep(SystemConfig.Instance.UsingStatus.ReleasePrecisionDelayInRobotUp);
                        }
                    }
                    else
                    {
                        if (isClamp)
                        {
                            if (isDelay)
                                Thread.Sleep(SystemConfig.Instance.UsingStatus.ClampPrecisionDelayBeforeInRobotDown);
                            if (isFeed)
                                MultiCylinderOperate(_downFeedPositionCylinder, 5000, new List<bool>() { true, true });
                            else
                                MultiCylinderOperate(_downRecyclePositionCylinder, 5000, new List<bool>() { true, true });
                            if (isDelay)
                                Thread.Sleep(SystemConfig.Instance.UsingStatus.ClampPrecisionDelayInRobotDown);
                        }
                        else
                        {
                            if (isDelay)
                                Thread.Sleep(SystemConfig.Instance.UsingStatus.ReleasePrecisionDelayBeforeInRobotDown);
                            if (isFeed)
                                MultiCylinderOperate(_downFeedPositionCylinder, 5000, new List<bool>() { false, false });
                            else
                                MultiCylinderOperate(_downRecyclePositionCylinder, 5000, new List<bool>() { false, false });
                            if (isDelay)
                                Thread.Sleep(SystemConfig.Instance.UsingStatus.ReleasePrecisionDelayInRobotDown);
                        }
                    }
                }
            }
        }
    }
    public enum RobotStatus
    {
        WaitTray,
        GetTray,
        PutProduct,
        PutGetPrecision,
    }
    public class RobotPoint
    {
        public double X { get; set; }
        public double Y { get; set; }
        public double R { get; set; }
        public RobotPoint()
        {

        }
        public RobotPoint(double x, double y, double r)
        {
            this.X = x; this.Y = y; this.R = r;
        }
        public override string ToString()
        {
            return $"{X.ToString("0.000")},{Y.ToString("0.000")},{R.ToString("0.000")}";
        }
    }
}
